diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f409a901 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +.idea \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/plugin.yml b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/plugin.yml new file mode 100644 index 00000000..e2beec57 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/plugin.yml @@ -0,0 +1,4 @@ +name: Mineplexer +main: mineplex.bungee.Mineplexer +version: 1 +author: defek7 diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/pom.xml b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/pom.xml new file mode 100644 index 00000000..9d466c56 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + Mineplexer + mineplex-bungee-mineplexer + + + + ${project.groupId} + mineplex-cache + ${project.version} + + + ${project.groupId} + mineplex-serverdata + ${project.version} + + + commons-codec + commons-codec + + + net.md-5 + bungeecord-proxy + 1.4.7-SNAPSHOT + + + diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/FileUpdater.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/FileUpdater.java new file mode 100644 index 00000000..06a6a0dc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/FileUpdater.java @@ -0,0 +1,171 @@ +package mineplex.bungee; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.plugin.Plugin; + +import org.apache.commons.codec.digest.DigestUtils; + +public class FileUpdater implements Runnable +{ + private Plugin _plugin; + private HashMap _jarMd5Map = new HashMap(); + + private boolean _needUpdate; + private boolean _enabled = true; + private int _timeTilRestart = 5; + + public FileUpdater(Plugin plugin) + { + _plugin = plugin; + + getPluginMd5s(); + + if (new File("IgnoreUpdates.dat").exists()) + _enabled = false; + + _plugin.getProxy().getScheduler().schedule(_plugin, this, 2L, 2L, TimeUnit.MINUTES); + } + + public void checkForNewFiles() + { + if (_needUpdate || !_enabled) + return; + + boolean windows = System.getProperty("os.name").startsWith("Windows"); + + File updateDir = new File((windows ? "C:" : File.separator + "home" + File.separator + "mineplex") + File.separator + "update"); + + updateDir.mkdirs(); + + FilenameFilter statsFilter = new FilenameFilter() + { + public boolean accept(File paramFile, String paramString) + { + if (paramString.endsWith("jar")) + { + return true; + } + + return false; + } + }; + + for (File f : updateDir.listFiles(statsFilter)) + { + FileInputStream fis = null; + + try + { + if (_jarMd5Map.containsKey(f.getName())) + { + fis = new FileInputStream(f); + String md5 = DigestUtils.md5Hex(fis); + + if (!md5.equals(_jarMd5Map.get(f.getName()))) + { + System.out.println(f.getName() + " old jar : " + _jarMd5Map.get(f.getName())); + System.out.println(f.getName() + " new jar : " + md5); + _needUpdate = true; + } + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + finally + { + if (fis != null) + { + try + { + fis.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + } + + private void getPluginMd5s() + { + File pluginDir = new File("plugins"); + + pluginDir.mkdirs(); + + FilenameFilter statsFilter = new FilenameFilter() + { + public boolean accept(File paramFile, String paramString) + { + if (paramString.endsWith("jar")) + { + return true; + } + + return false; + } + }; + + for (File f : pluginDir.listFiles(statsFilter)) + { + FileInputStream fis = null; + + try + { + fis = new FileInputStream(f); + _jarMd5Map.put(f.getName(), DigestUtils.md5Hex(fis)); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + finally + { + if (fis != null) + { + try + { + fis.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + } + + @Override + public void run() + { + checkForNewFiles(); + + if (_needUpdate) + { + BungeeCord.getInstance().broadcast(ChatColor.RED + "Connection Node" + ChatColor.DARK_GRAY + ">" + ChatColor.YELLOW + "This connection node will be restarting in " + _timeTilRestart + " minutes."); + } + else + { + return; + } + + _timeTilRestart -= 2; + + if (_timeTilRestart < 0 || !_enabled) + { + BungeeCord.getInstance().stop(); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java new file mode 100644 index 00000000..91039533 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/Mineplexer.java @@ -0,0 +1,21 @@ +package mineplex.bungee; + +import mineplex.bungee.lobbyBalancer.LobbyBalancer; +import mineplex.bungee.motd.MotdManager; +import mineplex.bungee.playerCount.PlayerCount; +import mineplex.bungee.playerStats.PlayerStats; +import mineplex.bungee.playerTracker.PlayerTracker; +import net.md_5.bungee.api.plugin.Plugin; + +public class Mineplexer extends Plugin +{ + @Override + public void onEnable() { + new MotdManager(this); + new LobbyBalancer(this); + new PlayerCount(this); + new FileUpdater(this); + new PlayerStats(this); + new PlayerTracker(this); + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java new file mode 100644 index 00000000..fca669fb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyBalancer.java @@ -0,0 +1,131 @@ +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 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 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 final Map> _sortedLobbyMap = new EnumMap<>(LobbyType.class); + private final Map _nextIndexMap = new EnumMap<>(LobbyType.class); + private static final LobbySorter LOBBY_SORTER = new LobbySorter(); + private static final Object _serverLock = new Object(); + + public LobbyBalancer(Plugin plugin) + { + _plugin = plugin; + + Region region = !new File("eu.dat").exists() ? Region.US : Region.EU; + _repository = ServerManager.getServerRepository(region); + + run(); + + _plugin.getProxy().getPluginManager().registerListener(_plugin, this); + _plugin.getProxy().getScheduler().schedule(_plugin, this, 500L, 500L, TimeUnit.MILLISECONDS); + } + + @EventHandler + public void playerConnect(ServerConnectEvent event) + { + Arrays.stream(LobbyType.values()) + .filter(type -> type.getConnectName().equalsIgnoreCase(event.getTarget().getName())) + .findFirst() + .ifPresent(lobbyType -> + { + synchronized (_serverLock) + { + List lobbies = _sortedLobbyMap.get(lobbyType); + + int nextIndex = _nextIndexMap.getOrDefault(lobbyType, 0); + if (nextIndex >= lobbies.size()) + { + nextIndex = 0; + } + + 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(); + + for (LobbyType type : LobbyType.values()) + { + 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)); + } + } + } + + public void loadServers() + { + Collection servers = _repository.getServerStatuses(); + + synchronized (_serverLock) + { + long startTime = System.currentTimeMillis(); + _sortedLobbyMap.clear(); + for (LobbyType type : LobbyType.values()) + { + _sortedLobbyMap.put(type, new ArrayList<>()); + } + + for (MinecraftServer server : servers) + { + if (server.getName() == null) + continue; + + InetSocketAddress socketAddress = new InetSocketAddress(server.getPublicAddress(), server.getPort()); + _plugin.getProxy().getServers().put(server.getName(), _plugin.getProxy().constructServerInfo(server.getName(), socketAddress, "LobbyBalancer", false)); + + if (server.getMotd() != null && server.getMotd().contains("Restarting")) + { + continue; + } + + 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"); + + _nextIndexMap.clear(); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbySorter.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbySorter.java new file mode 100644 index 00000000..dd975173 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbySorter.java @@ -0,0 +1,48 @@ +package mineplex.bungee.lobbyBalancer; + +import java.util.Comparator; + +import mineplex.serverdata.data.MinecraftServer; + +public class LobbySorter implements Comparator +{ + @Override + public int compare(MinecraftServer first, MinecraftServer second) + { + if (second.getPlayerCount() == 999) + return -1; + + if (first.getPlayerCount() == 999) + return 1; + + if (first.getPlayerCount() < (first.getMaxPlayerCount() / 2) && second.getPlayerCount() >= (second.getMaxPlayerCount() / 2)) + return -1; + + if (second.getPlayerCount() < (second.getMaxPlayerCount() / 2) && first.getPlayerCount() >= (first.getMaxPlayerCount() / 2)) + return 1; + + if (first.getPlayerCount() < (first.getMaxPlayerCount() / 2)) + { + if (first.getPlayerCount() > second.getPlayerCount()) + return -1; + + if (second.getPlayerCount() > first.getPlayerCount()) + return 1; + } + else + { + if (first.getPlayerCount() < second.getPlayerCount()) + return -1; + + if (second.getPlayerCount() < first.getPlayerCount()) + return 1; + } + + if (Integer.parseInt(first.getName().split("-")[1]) < Integer.parseInt(second.getName().split("-")[1])) + return -1; + else if (Integer.parseInt(second.getName().split("-")[1]) < Integer.parseInt(first.getName().split("-")[1])) + return 1; + + return 0; + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyType.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyType.java new file mode 100644 index 00000000..8b4e4fb5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/lobbyBalancer/LobbyType.java @@ -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; + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/GlobalMotd.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/GlobalMotd.java new file mode 100644 index 00000000..f8de8c52 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/GlobalMotd.java @@ -0,0 +1,43 @@ +package mineplex.bungee.motd; + +import java.util.List; + +import mineplex.serverdata.data.Data; + +/** + * A GlobalMotd represents a set of MOTD packaged lines. + * @author MrTwiggy + * + */ +public class GlobalMotd implements Data +{ + // The unique name representing this MOTD set + private String _name; + + private String _headline; + public String getHeadline() { return _headline; } + + // List of lines describing the MOTD + private List _motd; + public List getMotd() { return _motd; } + + /** + * Constructor + * @param name + * @param motd + */ + public GlobalMotd(String name, String headline, List motd) + { + _name = name; + _headline = headline; + _motd = motd; + } + + /** + * Unique identifying ID associated with this {@link GlobalMotd}. + */ + public String getDataId() + { + return _name; + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java new file mode 100644 index 00000000..4b556d2e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/motd/MotdManager.java @@ -0,0 +1,82 @@ +package mineplex.bungee.motd; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +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 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 final DataRepository _repository; + private final Random _random = new Random(); + private final Map motds = new EnumMap<>(LobbyType.class); + + public MotdManager(Plugin plugin) + { + plugin.getProxy().getScheduler().schedule(plugin, this, 5L, 30L, TimeUnit.SECONDS); + plugin.getProxy().getPluginManager().registerListener(plugin, this); + + _repository = new RedisDataRepository(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL), + Region.ALL, GlobalMotd.class, "globalMotd"); + run(); + } + + @EventHandler + public void serverPing(ProxyPingEvent event) + { + + net.md_5.bungee.api.ServerPing serverPing = event.getResponse(); + Optional maybeType = Optional.empty(); + + if (event.getConnection().getListener() != null) + { + 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())); + } + + @Override + public void run() + { + for (LobbyType type : LobbyType.values()) + { + GlobalMotd motd = _repository.getElement(type.getRedisMotdKey()); + + if (motd != null) + { + motds.put(type, motd); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java new file mode 100644 index 00000000..9c6cdfbc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerCount/PlayerCount.java @@ -0,0 +1,118 @@ +package mineplex.bungee.playerCount; + +import java.io.File; +import java.util.concurrent.TimeUnit; + +import mineplex.bungee.status.InternetStatus; +import mineplex.serverdata.Region; +import mineplex.serverdata.data.BungeeServer; +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.ServerPing.Players; +import net.md_5.bungee.api.config.ListenerInfo; +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; + +public class PlayerCount implements Listener, Runnable +{ + private DataRepository _repository; + private DataRepository _secondRepository; + private Region _region; + + private ListenerInfo _listenerInfo; + private Plugin _plugin; + + private int _totalPlayers = -1; + + public PlayerCount(Plugin plugin) + { + _region = !new File("eu.dat").exists() ? Region.US : Region.EU; + _plugin = plugin; + + _plugin.getProxy().getScheduler().schedule(_plugin, this, 4L, 4L, TimeUnit.SECONDS); + _plugin.getProxy().getPluginManager().registerListener(_plugin, this); + + for (ListenerInfo info : _plugin.getProxy().getConfigurationAdapter().getListeners()) + { + if (info.getDefaultServer().equalsIgnoreCase("Lobby")) + { + _listenerInfo = info; + } + } + + _repository = new RedisDataRepository(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL), + Region.ALL, BungeeServer.class, "bungeeServers"); + + if (_region == Region.US) + _secondRepository = new RedisDataRepository(new ConnectionData("10.81.1.156", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.81.1.156", 6377, ConnectionType.SLAVE, "ServerStatus"), + Region.ALL, BungeeServer.class, "bungeeServers"); + else + _secondRepository = new RedisDataRepository(new ConnectionData("10.33.53.16", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.33.53.16", 6377, ConnectionType.SLAVE, "ServerStatus"), + Region.ALL, BungeeServer.class, "bungeeServers"); + } + + public void run() + { + BungeeServer snapshot = generateSnapshot(); + if (snapshot != null) + { + _repository.addElement(snapshot, 15); // Update with a 15 second expiry on session + } + + _totalPlayers = fetchPlayerCount(); + } + + /** + * @return an up-to-date total player count across all active Bungee Servers. + */ + private int fetchPlayerCount() + { + int totalPlayers = 0; + for (BungeeServer server : _repository.getElements()) + { + totalPlayers += server.getPlayerCount(); + } + + for (BungeeServer server : _secondRepository.getElements()) + { + totalPlayers += server.getPlayerCount(); + } + + return totalPlayers; + } + + /** + * @return a newly instantiated {@link BungeeServer} snapshot of the current state of this server. + */ + private BungeeServer generateSnapshot() + { + if (_listenerInfo == null) + { + return null; + } + String name = _listenerInfo.getHost().getAddress().getHostAddress(); + String host = _listenerInfo.getHost().getAddress().getHostAddress(); + int port = _listenerInfo.getHost().getPort(); + boolean connected = InternetStatus.isConnected(); + int playerCount = _plugin.getProxy().getOnlineCount(); + return new BungeeServer(name, _region, host, port, playerCount, connected); + } + + @EventHandler + public void ServerPing(ProxyPingEvent event) + { + net.md_5.bungee.api.ServerPing serverPing = event.getResponse(); + + event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), new Players(_totalPlayers + 1, _totalPlayers, null), serverPing.getDescription(), serverPing.getFaviconObject())); + } + + public int getTotalPlayers() + { + return _totalPlayers; + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/PlayerStats.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/PlayerStats.java new file mode 100644 index 00000000..525d201c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/PlayerStats.java @@ -0,0 +1,141 @@ +package mineplex.bungee.playerStats; + +import java.util.HashSet; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import mineplex.bungee.playerStats.data.IpInfo; +import mineplex.cache.player.PlayerCache; +import mineplex.cache.player.PlayerInfo; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.event.EventHandler; + +public class PlayerStats implements Listener, Runnable +{ + private Plugin _plugin; + private PlayerStatsRepository _repository; + + private HashSet _retrievingPlayerInfo = new HashSet(); + + public PlayerStats(Plugin plugin) + { + _plugin = plugin; + + _plugin.getProxy().getScheduler().schedule(_plugin, this, 5L, 5L, TimeUnit.MINUTES); + _plugin.getProxy().getPluginManager().registerListener(_plugin, this); + + _repository = new PlayerStatsRepository(); + } + + @EventHandler + public void playerConnect(final PostLoginEvent event) + { + _plugin.getProxy().getScheduler().runAsync(_plugin, new Runnable() + { + public void run() + { + String address = event.getPlayer().getPendingConnection().getAddress().getAddress().getHostAddress(); + UUID uuid = event.getPlayer().getUniqueId(); + String name = event.getPlayer().getName(); + int version = event.getPlayer().getPendingConnection().getVersion(); + + try + { + PlayerInfo playerInfo = null; + IpInfo ipInfo = _repository.getIp(address); + + boolean addOrUpdatePlayer = false; + + playerInfo = PlayerCache.getInstance().getPlayer(uuid); + + if (playerInfo == null) + { + addOrUpdatePlayer = true; + _retrievingPlayerInfo.add(uuid); + } + + if (!addOrUpdatePlayer) + { + if (playerInfo.getVersion() != version) + addOrUpdatePlayer = true; + else if (!playerInfo.getName().equalsIgnoreCase(name)) + addOrUpdatePlayer = true; + } + + if (addOrUpdatePlayer) + { + // Just update? what about other properties? + PlayerInfo updatedPlayerInfo = _repository.getPlayer(uuid, name, version); + + if (playerInfo != null) + { + playerInfo.setName(updatedPlayerInfo.getName()); + playerInfo.setVersion(updatedPlayerInfo.getVersion()); + } + else + playerInfo = updatedPlayerInfo; + } + + playerInfo.setSessionId(_repository.updatePlayerStats(playerInfo.getId(), ipInfo.id)); + playerInfo.updateLoginTime(); + PlayerCache.getInstance().addPlayer(playerInfo); + } + finally + { + _retrievingPlayerInfo.remove(uuid); + } + } + }); + } + + @EventHandler + public void playerDisconnect(final PlayerDisconnectEvent event) + { + _plugin.getProxy().getScheduler().runAsync(_plugin, new Runnable() + { + public void run() + { + UUID uuid = event.getPlayer().getUniqueId(); + + PlayerInfo playerInfo = null; + + playerInfo = PlayerCache.getInstance().getPlayer(uuid); + + int timeout = 5; + + while (playerInfo == null && _retrievingPlayerInfo.contains(uuid) && timeout <= 5) + { + playerInfo = PlayerCache.getInstance().getPlayer(uuid); + + if (playerInfo != null) + break; + + System.out.println("ERROR - Player disconnecting and isn't in cache... sleeping"); + + try + { + Thread.sleep(500); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + timeout++; + } + + System.out.println(playerInfo.getName() + ":" + playerInfo.getSessionId()); + _repository.updatePlayerSession(playerInfo.getSessionId()); + } + }); + } + + @Override + public void run() + { + PlayerCache.getInstance().clean(); + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/PlayerStatsRepository.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/PlayerStatsRepository.java new file mode 100644 index 00000000..177972ad --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/PlayerStatsRepository.java @@ -0,0 +1,295 @@ +package mineplex.bungee.playerStats; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.UUID; + +import mineplex.bungee.playerStats.data.IpInfo; +import mineplex.cache.player.PlayerInfo; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; + +import javax.sql.DataSource; + +public class PlayerStatsRepository extends RepositoryBase +{ + private static String INSERT_PLAYERINFO = "INSERT INTO playerInfo (uuid, name, version) VALUES (?, ?, ?);"; + private static String SELECT_PLAYERINFO = "SELECT id, name, version FROM playerInfo WHERE uuid = ?;"; + private static String UPDATE_PLAYERINFO = "UPDATE playerInfo SET name = ?, version = ? WHERE id = ?;"; + + private static String INSERT_IPINFO = "INSERT INTO ipInfo (ipAddress) VALUES (?);"; + private static String SELECT_IPINFO = "SELECT id FROM ipInfo WHERE ipAddress = ?;"; + + private static String UPDATE_PLAYERSTATS = "INSERT IGNORE INTO playerIps (playerInfoId, ipInfoId, date) VALUES (?, ?, curdate());" + + "INSERT IGNORE INTO playerUniqueLogins (playerInfoId, day) values(?, curdate());" + + "INSERT IGNORE INTO playerLoginSessions (playerInfoId, loginTime) values(?, now());"; + + private static String UPDATE_LOGINSESSION = "UPDATE playerLoginSessions SET timeInGame = TIME_TO_SEC(TIMEDIFF(now(), loginTime)) / 60 WHERE id = ?;"; + + public PlayerStatsRepository() + { + super(DBPool.getPlayerStats()); + } + + public PlayerInfo getPlayer(UUID uuid, String name, int version) + { + PlayerInfo playerInfo = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(SELECT_PLAYERINFO); + + preparedStatement.setString(1, uuid.toString()); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + playerInfo = new PlayerInfo(resultSet.getInt(1), uuid, resultSet.getString(2), resultSet.getInt(3)); + } + + resultSet.close(); + preparedStatement.close(); + + if (playerInfo == null) + { + preparedStatement = connection.prepareStatement(INSERT_PLAYERINFO, Statement.RETURN_GENERATED_KEYS); + preparedStatement.setString(1, uuid.toString()); + preparedStatement.setString(2, name); + preparedStatement.setInt(3, version); + + preparedStatement.executeUpdate(); + + int id = 0; + + resultSet = preparedStatement.getGeneratedKeys(); + + while (resultSet.next()) + { + id = resultSet.getInt(1); + } + + playerInfo = new PlayerInfo(id, uuid, name, version); + + resultSet.close(); + preparedStatement.close(); + } + else if (!playerInfo.getName().equalsIgnoreCase(name) || playerInfo.getVersion() != version) + { + preparedStatement = connection.prepareStatement(UPDATE_PLAYERINFO); + preparedStatement.setString(1, name); + preparedStatement.setInt(2, version); + preparedStatement.setInt(3, playerInfo.getId()); + + preparedStatement.executeUpdate(); + preparedStatement.close(); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + if (resultSet != null) + { + try + { + resultSet.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return playerInfo; + } + + public IpInfo getIp(String ipAddress) + { + IpInfo ipInfo = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(SELECT_IPINFO); + preparedStatement.setString(1, ipAddress); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + ipInfo = new IpInfo(); + ipInfo.id = resultSet.getInt(1); + ipInfo.ipAddress = ipAddress; + } + + resultSet.close(); + preparedStatement.close(); + + if (ipInfo == null) + { + preparedStatement = connection.prepareStatement(INSERT_IPINFO, Statement.RETURN_GENERATED_KEYS); + preparedStatement.setString(1, ipAddress); + + preparedStatement.executeUpdate(); + + int id = 0; + + resultSet = preparedStatement.getGeneratedKeys(); + + while (resultSet.next()) + { + id = resultSet.getInt(1); + } + + ipInfo = new IpInfo(); + ipInfo.id = id; + ipInfo.ipAddress = ipAddress; + + resultSet.close(); + preparedStatement.close(); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + if (resultSet != null) + { + try + { + resultSet.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return ipInfo; + } + + public int updatePlayerStats(int playerId, int ipId) + { + Statement statement = null; + ResultSet resultSet= null; + + try(Connection connection = getConnection()) + { + statement = connection.createStatement(); + + String queryString = UPDATE_PLAYERSTATS; + queryString = queryString.replaceFirst("\\?", playerId + ""); + queryString = queryString.replaceFirst("\\?", ipId + ""); + queryString = queryString.replaceFirst("\\?", playerId + ""); + queryString = queryString.replaceFirst("\\?", playerId + ""); + + statement.executeUpdate(queryString, Statement.RETURN_GENERATED_KEYS); + + statement.getMoreResults(); + statement.getMoreResults(); + resultSet = statement.getGeneratedKeys(); + + while (resultSet.next()) + { + return resultSet.getInt(1); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + try + { + if (statement != null) + statement.close(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + + try + { + if (resultSet != null) + resultSet.close(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + } + + return -1; + } + + public void updatePlayerSession(int loginSessionId) + { + PreparedStatement preparedStatement = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(UPDATE_LOGINSESSION); + preparedStatement.setInt(1, loginSessionId); + + preparedStatement.executeUpdate(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/data/IpInfo.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/data/IpInfo.java new file mode 100644 index 00000000..ab2c0996 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerStats/data/IpInfo.java @@ -0,0 +1,7 @@ +package mineplex.bungee.playerStats.data; + +public class IpInfo +{ + public int id; + public String ipAddress; +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerJoinHandler.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerJoinHandler.java new file mode 100644 index 00000000..19c52c0a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerJoinHandler.java @@ -0,0 +1,26 @@ +package mineplex.bungee.playerTracker; + +import java.util.UUID; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.PlayerJoinCommand; +import mineplex.serverdata.commands.ServerCommand; + +public class PlayerJoinHandler implements CommandCallback +{ + private PlayerTracker _playerTracker; + + public PlayerJoinHandler(PlayerTracker playerTracker) + { + _playerTracker = playerTracker; + } + + @Override + public void run(ServerCommand command) + { + if (command instanceof PlayerJoinCommand) + { + PlayerJoinCommand joinCommand = (PlayerJoinCommand)command; + _playerTracker.kickPlayerIfOnline(UUID.fromString(joinCommand.getUuid())); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java new file mode 100644 index 00000000..a8370432 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java @@ -0,0 +1,108 @@ +package mineplex.bungee.playerTracker; + +import java.util.List; +import java.util.UUID; + +import com.google.common.collect.Lists; +import com.google.gson.Gson; + +import mineplex.serverdata.Region; +import mineplex.serverdata.commands.PlayerJoinCommand; +import mineplex.serverdata.commands.ServerCommandManager; +import mineplex.serverdata.data.DataRepository; +import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.event.ServerConnectedEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.event.EventHandler; + +public class PlayerTracker implements Listener +{ + // Default period before status expiry (8 hours) + private static final int DEFAULT_STATUS_TIMEOUT = 60 * 60 * 8; + + // Repository storing player status' across network. + private DataRepository _repository; + + private Plugin _plugin; + + private final List _ignoreKick = Lists.newArrayList(); + + public PlayerTracker(Plugin plugin) + { + _plugin = plugin; + + _plugin.getProxy().getPluginManager().registerListener(_plugin, this); + + _repository = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), + Region.currentRegion(), PlayerStatus.class, "playerStatus"); + + ServerCommandManager.getInstance().initializeServer("BUNGEE ENABLE - " + System.currentTimeMillis(), new Gson()); + ServerCommandManager.getInstance().registerCommandType(mineplex.serverdata.commands.PlayerJoinCommand.class, new PlayerJoinHandler(this)); + + System.out.println("Initialized PlayerTracker."); + } + + public Plugin getPlugin() + { + return _plugin; + } + + @EventHandler + public void playerConnect(final ServerConnectedEvent event) + { + _plugin.getProxy().getScheduler().runAsync(_plugin, new Runnable() + { + public void run() + { + PlayerStatus snapshot = new PlayerStatus(event.getPlayer().getUniqueId(), event.getPlayer().getName(), event.getServer().getInfo().getName()); + _repository.addElement(snapshot, DEFAULT_STATUS_TIMEOUT); + } + }); + } + + @EventHandler + public void playerDisconnect(final PlayerDisconnectEvent event) + { + _plugin.getProxy().getScheduler().runAsync(_plugin, new Runnable() + { + public void run() + { + _repository.removeElement(event.getPlayer().getUniqueId().toString()); + } + }); + } + + @EventHandler + public void playerConnect(final PostLoginEvent event) + { + _ignoreKick.add(event.getPlayer().getUniqueId()); + PlayerJoinCommand command = new PlayerJoinCommand(event.getPlayer().getUniqueId(), event.getPlayer().getName()); + command.publish(); + } + + public boolean isPlayerOnline(UUID uuid) + { + return _plugin.getProxy().getPlayer(uuid) != null; + } + + public void kickPlayerIfOnline(UUID uuid) + { + if (_ignoreKick.remove(uuid)) + { + return; + } + if (isPlayerOnline(uuid)) + { + ProxiedPlayer player = _plugin.getProxy().getPlayer(uuid); + + player.disconnect(new TextComponent("You have logged in from another location.")); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/status/InternetStatus.java b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/status/InternetStatus.java new file mode 100644 index 00000000..f4ee8ef8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/status/InternetStatus.java @@ -0,0 +1,55 @@ +package mineplex.bungee.status; + +import java.io.File; +import java.io.IOException; +import java.net.Socket; +import java.util.concurrent.TimeUnit; + +import net.md_5.bungee.api.config.ListenerInfo; +import net.md_5.bungee.api.plugin.Plugin; + +public class InternetStatus implements Runnable +{ + // Current internet connectivity status + private static boolean _connected = true; + public static boolean isConnected() { return _connected; } + + private Plugin _plugin; + + public InternetStatus(Plugin plugin) + { + _plugin = plugin; + _plugin.getProxy().getScheduler().schedule(_plugin, this, 1L, 1L, TimeUnit.MINUTES); + + System.out.println("Initialized InternetStatus."); + } + + @Override + public void run() + { + _connected = isOnline(); // Update _connected flag. + } + + private boolean isOnline() + { + return testUrl("www.google.com") + || testUrl("www.espn.com") + || testUrl("www.bing.com"); + } + + private boolean testUrl(String url) + { + boolean reachable = false; + + try (Socket socket = new Socket(url, 80)) + { + reachable = true; + } + catch (Exception e) + { + // Meh i don't care + } + + return reachable; + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/pom.xml b/Plugins[Modified]/Mineplex.BungeeRotator/pom.xml new file mode 100644 index 00000000..3118cb50 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + + com.mineplex + mineplex-app + dev-SNAPSHOT + ../app.xml + + + BungeeRotator + mineplex-bungeerotator + + + + ${project.groupId} + mineplex-serverdata + ${project.version} + + + org.apache.httpcomponents + httpclient + 4.5.2 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + mineplex.bungee.BungeeRotator + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4 + + + package + + shade + + + true + + + org.apache.commons:commons-pool2 + + ** + + + + commons-logging:commons-logging + + ** + + + + + + + + + + diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/BungeeRotator.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/BungeeRotator.java new file mode 100644 index 00000000..12ff80b0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/BungeeRotator.java @@ -0,0 +1,308 @@ +package mineplex.bungee; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.logging.FileHandler; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import mineplex.bungee.api.ApiDeleteCall; +import mineplex.bungee.api.ApiGetCall; +import mineplex.bungee.api.ApiPostCall; +import mineplex.bungee.api.HttpCallBase; +import mineplex.bungee.api.token.ARecord; +import mineplex.bungee.api.token.DnsRecord; +import mineplex.bungee.api.token.DomainRecords; +import mineplex.serverdata.Region; +import mineplex.serverdata.data.BungeeServer; +import mineplex.serverdata.data.DataRepository; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ConnectionData; +import mineplex.serverdata.servers.ServerManager; +import mineplex.serverdata.servers.ConnectionData.ConnectionType; + +public class BungeeRotator +{ + private static DataRepository _repository; + private static DataRepository _secondRepository; + private static PlayerStatsRepository _ipRepository; + //private static ServerRepository _repository = null; + + private static SimpleDateFormat _dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + private static Logger _logger = Logger.getLogger("BungeeRotator"); + private static boolean _debug = false; + + public static void main(String args[]) + { + try + { + FileHandler fileHandler = new FileHandler("rotator.log", true); + fileHandler.setFormatter(new Formatter() + { + @Override + public String format(LogRecord record) + { + return record.getMessage() + "\n"; + } + }); + _logger.addHandler(fileHandler); + _logger.setUseParentHandlers(false); + } + catch (SecurityException | IOException e1) + { + e1.printStackTrace(); + } + + + /* + String username = "mineplex"; + String password = "gjxcVf%nk."; + String accountId = null; + + try { + UltraAPIClient ultraAPIClient = new UltraAPIClientImpl(username, password); + System.out.println(ultraAPIClient.getNeustarNetworkStatus()); + AccountDetailsList accountDetailsForUser = ultraAPIClient.getAccountDetailsForUser(); + System.out.println(accountDetailsForUser.getAccountDetailsData().get(0).getAccountID()); + if (accountId == null) { + accountId = accountDetailsForUser.getAccountDetailsData().get(0).getAccountID(); + } + String zoneName = RandomStringUtils.randomAlphanumeric(16).toLowerCase()+".com."; + try { + //System.out.println(ultraAPIClient.deleteZone(zoneName)); + } catch (UltraAPIException e) { + e.printStackTrace(); + if (e.getCode() != 1801) { + System.exit(1); + } + } + System.out.println(ultraAPIClient.createPrimaryZone(accountId, zoneName)); + System.out.println(ultraAPIClient.getSecondaryZonesOfAccount(accountId)); + System.out.println(ultraAPIClient.createARecord(zoneName, "foo."+zoneName, "1.2.3.4", 86400)); + //System.out.println(ultraAPIClient.deleteZone(zoneName)); + } catch (UltraAPIException e) { + e.printStackTrace(); + } + + */ + _debug = new File("debug.dat").exists(); + + _repository = new RedisDataRepository(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL), + Region.ALL, BungeeServer.class, "bungeeServers"); + + _secondRepository = new RedisDataRepository(new ConnectionData("10.81.1.156", 6379, ConnectionType.MASTER, "ServerStatus"), new ConnectionData("10.81.1.156", 6377, ConnectionType.SLAVE, "ServerStatus"), + Region.ALL, BungeeServer.class, "bungeeServers"); + + //_ipRepository = new PlayerStatsRepository(); + + BungeeSorter bungeeSorter = new BungeeSorter(); + int maxRecordCount = 10; + + while (true) + { + try + { + List bungeeServers = new ArrayList(_repository.getElements()); + bungeeServers.addAll(_secondRepository.getElements()); + + Collections.sort(bungeeServers, bungeeSorter); + + if (_debug) + { + int totalPlayers = 0; + int usPlayers = 0; + int euPlayers = 0; + + for (BungeeServer server : bungeeServers) + { + if (server.getPublicAddress().equalsIgnoreCase("127.0.0.1") || server.getPublicAddress().equalsIgnoreCase("0.0.0.0")) + continue; + + totalPlayers += server.getPlayerCount(); + + if (server.getRegion() == Region.US) + usPlayers += server.getPlayerCount(); + else + euPlayers += server.getPlayerCount(); + + System.out.println(server.getRegion().toString() + " " + server.getName() + " " + server.getPublicAddress() + " " + server.getPlayerCount() + "/" + server.getPlayerCount()); + } + + System.out.println("US Players : " + usPlayers); + System.out.println("EU Players : " + euPlayers); + System.out.println("Total Players : " + totalPlayers); + System.out.println("Count : " + bungeeServers.size()); + } + else + { + HashSet usServers = new HashSet(); + HashSet euServers = new HashSet(); + + + for (BungeeServer server : bungeeServers) + { + if (server.getPublicAddress().equalsIgnoreCase("127.0.0.1")) + continue; + + if (usServers.size() < maxRecordCount && server.getRegion() == Region.US) + { + if (usServers.size() >= 2 && server.getPlayerCount() > 900) + continue; + + log("SELECTED " + server.getPublicAddress() + " " + (server.getRegion() == Region.US ? "us" : "eu") + " " + server.getPlayerCount() + "/" + server.getPlayerCount()); + usServers.add(server.getPublicAddress()); + } + else if (euServers.size() < maxRecordCount && server.getRegion() != Region.US) + { + if (euServers.size() >= 2 && server.getPlayerCount() > 900) + continue; + + log("SELECTED " + server.getPublicAddress() + " " + (server.getRegion() == Region.US ? "us" : "eu") + " " + server.getPlayerCount() + "/" + server.getPlayerCount()); + euServers.add(server.getPublicAddress()); + } + } + + DomainRecords records = new ApiGetCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, + "/records", "").Execute(DomainRecords.class); + List recordsToDelete = new ArrayList(); + List recordsToAdd = new ArrayList(); + + for (DnsRecord record : records.data) + { + if (record.type.equalsIgnoreCase("A")) + { + if (record.name.equalsIgnoreCase("us")) + { + if (usServers.contains(record.value)) + usServers.remove(record.value); + else + recordsToDelete.add(record); + } + else if (record.name.equalsIgnoreCase("eu")) + { + if (euServers.contains(record.value)) + euServers.remove(record.value); + else + recordsToDelete.add(record); + } + } + } + + for (String address : usServers) + { + recordsToAdd.add(new ARecord("us", address, 300)); + log("Adding server address in DNS : " + "us " + address); + } + + if (recordsToAdd.size() > 0) + { + new ApiPostCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records/", "createMulti").Execute(recordsToAdd); + log("Created " + recordsToAdd.size() + " records."); + } + + recordsToAdd.clear(); + + for (String address : euServers) + { + recordsToAdd.add(new ARecord("eu", address, 300)); + log("Adding server address in DNS : " + "eu " + address); + } + + if (recordsToAdd.size() > 0) + { + new ApiPostCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records/", "createMulti").Execute(recordsToAdd); + log("Created " + recordsToAdd.size() + " records."); + } + recordsToAdd.clear(); + + + if (recordsToDelete.size() > 0) + { + StringBuilder idBuilder = new StringBuilder(); + + for (DnsRecord record : recordsToDelete) + { + if (idBuilder.length() != 0) + idBuilder.append("&"); + + idBuilder.append("ids=" + record.id); + } + + new ApiDeleteCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records?" + idBuilder.toString()).Execute(); + log("Deleted " + recordsToDelete.size() + " records."); + } + + _repository.clean(); + _secondRepository.clean(); + } + + /* + List updatedAddresses = new ArrayList(1000); + + for (IpInfo ipInfo : _ipRepository.getIpAddresses()) + { + IPGeoData recor = new HttpCallBase("http://www.freegeoip.net/json/" + ipInfo.ipAddress).Execute(IPGeoData.class); + ipInfo.countryCode = recor.country_code; + ipInfo.countryName = recor.country_name; + ipInfo.regionCode = recor.region_code; + ipInfo.regionName = recor.region_name; + ipInfo.city = recor.city; + ipInfo.zipCode = recor.zip_code; + ipInfo.timeZone = recor.time_zone; + ipInfo.latitude = recor.latitude; + ipInfo.longitude = recor.longitude; + ipInfo.metroCode = recor.metro_code; + + updatedAddresses.add(ipInfo); + } + + _ipRepository.updateIps(updatedAddresses); + */ + try + { + Thread.sleep(15000); + log("Natural Sleep"); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + } + catch (Exception ex) + { + ex.printStackTrace(); + log("Error doing something : " + ex.getMessage()); + + try + { + Thread.sleep(1000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } + } + + private static void log(String message) + { + log(message, false); + } + + private static void log(String message, boolean fileOnly) + { + _logger.info("[" + _dateFormat.format(new Date()) + "] " + message); + + if (!fileOnly) + System.out.println("[" + _dateFormat.format(new Date()) + "] " + message); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/BungeeSorter.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/BungeeSorter.java new file mode 100644 index 00000000..4bcdf55d --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/BungeeSorter.java @@ -0,0 +1,19 @@ +package mineplex.bungee; + +import java.util.Comparator; + +import mineplex.serverdata.data.BungeeServer; + +public class BungeeSorter implements Comparator +{ + public int compare(BungeeServer a, BungeeServer b) + { + if (a.getPlayerCount() < b.getPlayerCount()) + return -1; + + if (b.getPlayerCount() < a.getPlayerCount()) + return 1; + + return 0; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/GenericRunnable.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/GenericRunnable.java new file mode 100644 index 00000000..4a82613f --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/GenericRunnable.java @@ -0,0 +1,6 @@ +package mineplex.bungee; + +public interface GenericRunnable +{ + void run(T t); +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/IPGeoData.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/IPGeoData.java new file mode 100644 index 00000000..9988f681 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/IPGeoData.java @@ -0,0 +1,16 @@ +package mineplex.bungee; + +public class IPGeoData +{ + public String ip; + public String country_code; + public String country_name; + public String region_code; + public String region_name; + public String city; + public String zip_code; + public String time_zone; + public double latitude; + public double longitude; + public int metro_code; +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/IpInfo.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/IpInfo.java new file mode 100644 index 00000000..44ad87a9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/IpInfo.java @@ -0,0 +1,17 @@ +package mineplex.bungee; + +public class IpInfo +{ + public int id; + public String ipAddress; + public String countryCode; + public String countryName; + public String regionCode; + public String regionName; + public String city; + public String zipCode; + public String timeZone; + public double latitude; + public double longitude; + public int metroCode; +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/PlayerStatsRepository.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/PlayerStatsRepository.java new file mode 100644 index 00000000..9cd06532 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/PlayerStatsRepository.java @@ -0,0 +1,124 @@ +package mineplex.bungee; + +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +public class PlayerStatsRepository extends RepositoryBase +{ + private static String SELECT_IPINFO = "SELECT id, ipAddress FROM ipInfo WHERE regionName IS NULL LIMIT 1000;"; + private static String UPDATE_IPINFO = "UPDATE ipInfo SET countryCode = ?, countryName = ?, regionCode = ?, regionName = ?, city = ?, zipCode = ?, timeZone = ?, latitude = ?, longitude = ?, metroCode = ? WHERE id = ?;"; + + public PlayerStatsRepository() + { + super(DBPool.getPlayerStats()); + } + + public List getIpAddresses() + { + List ipinfos = new ArrayList(1000); + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(SELECT_IPINFO); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + IpInfo ipInfo = new IpInfo(); + ipInfo.id = resultSet.getInt(1); + ipInfo.ipAddress = resultSet.getString(2); + + ipinfos.add(ipInfo); + } + + resultSet.close(); + preparedStatement.close(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + if (resultSet != null) + { + try + { + resultSet.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return ipinfos; + } + + public void updateIps(List ips) + { + PreparedStatement preparedStatement = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(UPDATE_IPINFO); + + for (IpInfo ipInfo : ips) + { + preparedStatement.setString(1, ipInfo.countryCode); + preparedStatement.setString(2, ipInfo.countryName); + preparedStatement.setString(3, ipInfo.regionCode); + preparedStatement.setString(4, ipInfo.regionName); + preparedStatement.setString(5, ipInfo.city); + preparedStatement.setString(6, ipInfo.zipCode); + preparedStatement.setString(7, ipInfo.timeZone); + preparedStatement.setDouble(8, ipInfo.latitude); + preparedStatement.setDouble(9, ipInfo.longitude); + preparedStatement.setInt(10, ipInfo.metroCode); + preparedStatement.setInt(11, ipInfo.id); + + preparedStatement.addBatch(); + } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/ProcessRunner.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/ProcessRunner.java new file mode 100644 index 00000000..27ba8323 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/ProcessRunner.java @@ -0,0 +1,81 @@ +package mineplex.bungee; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class ProcessRunner extends Thread +{ + private ProcessBuilder _processBuilder; + private Process _process; + private GenericRunnable _runnable; + + boolean _done = false; + Boolean _error = false; + + ProcessRunner(String[] args) + { + super("ProcessRunner " + args); + _processBuilder = new ProcessBuilder(args); + } + + public void run() + { + try + { + _process = _processBuilder.start(); + _process.waitFor(); + + BufferedReader reader=new BufferedReader(new InputStreamReader(_process.getInputStream())); + String line = reader.readLine(); + + while(line != null) + { + if (line.equals("255")) + _error = true; + + line=reader.readLine(); + } + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + finally + { + _done = true; + + if (_runnable != null) + _runnable.run(_error); + } + } + + public void start(GenericRunnable runnable) + { + super.start(); + + _runnable = runnable; + } + + public int exitValue() throws IllegalStateException + { + if (_process != null) + { + return _process.exitValue(); + } + + throw new IllegalStateException("Process not started yet"); + } + + public boolean isDone() + { + return _done; + } + + public void abort() + { + if (!isDone()) + { + _process.destroy(); + } + } + } diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiDeleteCall.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiDeleteCall.java new file mode 100644 index 00000000..57c24889 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiDeleteCall.java @@ -0,0 +1,18 @@ +package mineplex.bungee.api; + +import org.apache.http.client.methods.HttpDelete; + +public class ApiDeleteCall extends DnsMadeEasyApiCallBase +{ + public ApiDeleteCall(String apiUrl, int domainId, String category) + { + super(apiUrl, domainId, category); + } + + public void Execute() + { + HttpDelete request = new HttpDelete(ApiUrl + DomainId + Category); + + execute(request); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiGetCall.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiGetCall.java new file mode 100644 index 00000000..a28aaa14 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiGetCall.java @@ -0,0 +1,33 @@ +package mineplex.bungee.api; + +import java.lang.reflect.Type; + +import org.apache.http.client.methods.HttpGet; + +import com.google.gson.Gson; + +public class ApiGetCall extends DnsMadeEasyApiCallBase +{ + private String _action; + + public ApiGetCall(String apiUrl, int domainId, String category, String action) + { + super(apiUrl, domainId, category); + + _action = action; + } + + public void Execute() + { + HttpGet request = new HttpGet(ApiUrl + DomainId + Category + _action); + execute(request); + } + + public T Execute(Type returnType) + { + HttpGet request = new HttpGet(ApiUrl + DomainId + Category + _action); + + String response = execute(request); + return new Gson().fromJson(response, returnType); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiPostCall.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiPostCall.java new file mode 100644 index 00000000..26d60538 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiPostCall.java @@ -0,0 +1,77 @@ +package mineplex.bungee.api; + +import java.lang.reflect.Type; + +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +public class ApiPostCall extends DnsMadeEasyApiCallBase +{ + private String _action; + + public ApiPostCall(String apiUrl, int domainId, String category, String action) + { + super(apiUrl, domainId, category); + + _action = action; + } + + public void Execute(Object argument) + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(ApiUrl + DomainId + Category + _action); + + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPostCall(Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + execute(request); + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(ApiUrl + DomainId + Category + _action); + System.out.println(request.getURI().toString()); + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPostCall(Type, Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + String response = execute(request); + System.out.println(response); + return new Gson().fromJson(response, returnType); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiPutCall.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiPutCall.java new file mode 100644 index 00000000..bfe4bdd8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/ApiPutCall.java @@ -0,0 +1,79 @@ +package mineplex.bungee.api; + +import java.lang.reflect.Type; + +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +public class ApiPutCall extends DnsMadeEasyApiCallBase +{ + private String _action; + + public ApiPutCall(String apiUrl, int domainId, String category, String action) + { + super(apiUrl, domainId, category); + + _action = action; + } + + public void Execute(Object argument) + { + Gson gson = new Gson(); + HttpPut request = new HttpPut(ApiUrl + DomainId + Category + _action); + + System.out.println(request.getURI().toString()); + + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPutCall(Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + System.out.println(execute(request)); + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + Gson gson = new Gson(); + HttpPut request = new HttpPut(ApiUrl + DomainId + Category + _action); + System.out.println(request.getURI().toString()); + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPutCall(Type, Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + String response = execute(request); + System.out.println(response); + return new Gson().fromJson(response, returnType); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/DnsMadeEasyApiCallBase.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/DnsMadeEasyApiCallBase.java new file mode 100644 index 00000000..e8aa90d3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/DnsMadeEasyApiCallBase.java @@ -0,0 +1,137 @@ +package mineplex.bungee.api; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.codec.binary.Hex; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +public abstract class DnsMadeEasyApiCallBase +{ + public static final int TIMEOUT = (int) TimeUnit.SECONDS.toMillis(60); + + protected String ApiUrl = "https://api.dnsmadeeasy.com/V2.0/dns/managed/"; + protected int DomainId = 962728; + protected String Category = "/records/"; + + public DnsMadeEasyApiCallBase(String apiUrl, int domainId, String category) + { + ApiUrl = apiUrl; + DomainId = domainId; + Category = category; + } + + protected String execute(HttpRequestBase request) + { + PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(); + connectionManager.setMaxTotal(200); + connectionManager.setDefaultMaxPerRoute(20); + + HttpParams params = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(params, TIMEOUT); + HttpClient httpClient = new DefaultHttpClient(connectionManager, params); + InputStream in = null; + String response = ""; + + try + { + String timeStamp = getServerTime(); + SecretKeySpec keySpec = new SecretKeySpec("9041bc01-5cbc-49cf-ae09-a23b98350c62".getBytes(), "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(keySpec); + byte[] hashBytes = mac.doFinal((timeStamp + "").getBytes()); + Hex.encodeHexString(hashBytes); + + request.addHeader("x-dnsme-apiKey", "2039c697-6ca9-412f-abda-0aef659a382a"); + request.addHeader("x-dnsme-requestDate", timeStamp + ""); + request.addHeader("x-dnsme-hmac", Hex.encodeHexString(hashBytes)); + request.addHeader("Content-Type", "application/json"); + + HttpResponse httpResponse = httpClient.execute(request); + + if (httpResponse != null) + { + in = httpResponse.getEntity().getContent(); + response = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("DnsMadeEasyApiCall Error:"); + ex.printStackTrace(); + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return response; + } + + protected String getServerTime() + { + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + return dateFormat.format(calendar.getTime()); + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try + { + while ((line = reader.readLine()) != null) + { + sb.append(line + "\n"); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + finally + { + try + { + is.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/HttpCallBase.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/HttpCallBase.java new file mode 100644 index 00000000..d4e7b83b --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/HttpCallBase.java @@ -0,0 +1,122 @@ +package mineplex.bungee.api; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; + +import com.google.gson.Gson; + +public class HttpCallBase +{ + private String _url; + + public HttpCallBase(String url) + { + _url = url; + } + + public T Execute(Type returnType) + { + HttpGet request = new HttpGet(_url); + + String response = execute(request); + System.out.println(response); + return new Gson().fromJson(response, returnType); + } + + protected String execute(HttpRequestBase request) + { + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + + PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(schemeRegistry); + connectionManager.setMaxTotal(200); + connectionManager.setDefaultMaxPerRoute(20); + + HttpClient httpClient = new DefaultHttpClient(connectionManager); + InputStream in = null; + String response = ""; + + try + { + request.addHeader("Content-Type", "application/json"); + HttpResponse httpResponse = httpClient.execute(request); + + if (httpResponse != null) + { + in = httpResponse.getEntity().getContent(); + response = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("HttpCall Error:\n" + ex.getMessage()); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return response; + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try + { + while ((line = reader.readLine()) != null) + { + sb.append(line + "\n"); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + finally + { + try + { + is.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/ARecord.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/ARecord.java new file mode 100644 index 00000000..f8e66dea --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/ARecord.java @@ -0,0 +1,14 @@ +package mineplex.bungee.api.token; + +public class ARecord extends DnsRecord +{ + public ARecord(String recordName, String ip, int recordTtl) + { + name = recordName; + value = ip; + ttl = recordTtl; + + type = "A"; + gtdLocation = "DEFAULT"; + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/CNameRecord.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/CNameRecord.java new file mode 100644 index 00000000..e928daa8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/CNameRecord.java @@ -0,0 +1,14 @@ +package mineplex.bungee.api.token; + +public class CNameRecord extends DnsRecord +{ + public CNameRecord(String recordName, String ip, int recordTtl) + { + name = recordName; + value = ip; + ttl = recordTtl; + + type = "CNAME"; + gtdLocation = "DEFAULT"; + } +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/DnsRecord.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/DnsRecord.java new file mode 100644 index 00000000..469b600b --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/DnsRecord.java @@ -0,0 +1,11 @@ +package mineplex.bungee.api.token; + +public class DnsRecord +{ + public int id; + public String name; + public String type; + public String value; + public String gtdLocation = "DEFAULT"; + public int ttl; +} diff --git a/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/DomainRecords.java b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/DomainRecords.java new file mode 100644 index 00000000..79308ce7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.BungeeRotator/src/mineplex/bungee/api/token/DomainRecords.java @@ -0,0 +1,11 @@ +package mineplex.bungee.api.token; + +import java.util.List; + +public class DomainRecords +{ + public List data; + public int page; + public int totalPage; + public int totalRecords; +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/AccountTask.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/AccountTask.java new file mode 100644 index 00000000..122dbc58 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/AccountTask.java @@ -0,0 +1,8 @@ +package mineplex.chestConverter; + +public class AccountTask +{ + public int Id; + public String Task; + public String UUID; +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/AsyncJsonWebCall.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/AsyncJsonWebCall.java new file mode 100644 index 00000000..63e3812e --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/AsyncJsonWebCall.java @@ -0,0 +1,63 @@ +package mineplex.chestConverter; + +import mineplex.core.common.util.Callback; + +public class AsyncJsonWebCall extends JsonWebCall +{ + public AsyncJsonWebCall(String url) + { + super(url); + } + + public void Execute() + { + Thread asyncThread = new Thread(new Runnable() + { + public void run() + { + AsyncJsonWebCall.super.Execute(); + } + }); + + asyncThread.start(); + } + + public void Execute(final Object argument) + { + Thread asyncThread = new Thread(new Runnable() + { + public void run() + { + AsyncJsonWebCall.super.Execute(argument); + } + }); + + asyncThread.start(); + } + + public void Execute(final Class callbackClass, final Callback callback) + { + Thread asyncThread = new Thread(new Runnable() + { + public void run() + { + AsyncJsonWebCall.super.Execute(callbackClass, callback); + } + }); + + asyncThread.start(); + } + + public void Execute(final Class callbackClass, final Callback callback, final Object argument) + { + Thread asyncThread = new Thread(new Runnable() + { + public void run() + { + AsyncJsonWebCall.super.Execute(callbackClass, callback, argument); + } + }); + + asyncThread.start(); + } +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/ChestConverter.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/ChestConverter.java new file mode 100644 index 00000000..f1fd646d --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/ChestConverter.java @@ -0,0 +1,204 @@ +package mineplex.chestConverter; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.logging.FileHandler; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public class ChestConverter +{ + private static ChestConverterRepository _repository = null; + private static SimpleDateFormat _dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + + private static Logger _logger = Logger.getLogger("Converter"); + + private static String _connectionString = "jdbc:mysql://db.mineplex.com:3306/Account?allowMultiQueries=true"; + private static String _userName = "MilitaryPolice"; + private static String _password = "CUPr6Wuw2Rus$qap"; + + private static Connection _connection; + + public static void main (String args[]) + { + try + { + Class.forName("com.mysql.jdbc.Driver"); + } + catch (ClassNotFoundException e1) + { + e1.printStackTrace(); + } + + try + { + FileHandler fileHandler = new FileHandler("converter.log", true); + fileHandler.setFormatter(new Formatter() + { + @Override + public String format(LogRecord record) + { + return record.getMessage() + "\n"; + } + }); + _logger.addHandler(fileHandler); + _logger.setUseParentHandlers(false); + } + catch (SecurityException | IOException e1) + { + e1.printStackTrace(); + } + + int limit = 50000; + HashSet accountStats = new HashSet(); + + while (true) + { + accountStats.clear(); + + try + { + Statement statement = null; + + try + { + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + statement = _connection.createStatement(); + + statement.execute("SELECT accountId, statId, value FROM Account.accountStats LIMIT " + limit + ";"); + + ResultSet resultSet = statement.getResultSet(); + + while (resultSet.next()) + { + accountStats.add(new AccountStat(resultSet.getInt(1), resultSet.getInt(2), resultSet.getInt(3))); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (statement != null) + { + try + { + statement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + if (accountStats.size() == 0) + { + System.out.println("No accounts."); + return; + } + + PreparedStatement updateStatement = null; + PreparedStatement insertStatement = null; + Statement deleteStatement = null; + + try + { + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + _connection.setAutoCommit(true); + updateStatement = _connection.prepareStatement("UPDATE accountStat SET value = value + ? WHERE accountId = ? AND statId = ? AND value < ?;"); + + for (AccountStat stat : accountStats) + { + updateStatement.setLong(1, stat.value); + updateStatement.setInt(2, stat.accountId); + updateStatement.setInt(3, stat.statId); + updateStatement.setLong(4, stat.value); + + updateStatement.addBatch(); + } + + int[] rowsAffected = updateStatement.executeBatch(); + _connection.setAutoCommit(false); + int i = 0; + int count = 0; + + log("Updated rows - " + limit); + + insertStatement = _connection.prepareStatement("INSERT IGNORE accountStat(accountId, statId, value) VALUES (?, ?, ?);"); + + for (AccountStat stat : accountStats) + { + if (rowsAffected[i] < 1) + { + insertStatement.setInt(1, stat.accountId); + insertStatement.setInt(2, stat.statId); + insertStatement.setLong(3, stat.value); + + insertStatement.addBatch(); + count++; + } + + i++; + } + + insertStatement.executeBatch(); + log("Inserted rows - " + count); + + deleteStatement = _connection.createStatement(); + deleteStatement.executeUpdate("DELETE FROM accountStats LIMIT " + limit + ";"); + + _connection.commit(); + + log("Deleted rows - " + limit); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (statement != null) + { + try + { + statement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + catch (Exception e) + { + _logger.info(e.getMessage()); + } + } + } + + private static void log(String message) + { + System.out.println("[" + _dateFormat.format(new Date()) + "] " + message); + } +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/ChestConverterRepository.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/ChestConverterRepository.java new file mode 100644 index 00000000..fcb0107c --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/ChestConverterRepository.java @@ -0,0 +1,174 @@ +package mineplex.chestConverter; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +public class ChestConverterRepository +{ + private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/Account?allowMultiQueries=true"; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private static String ADD_ACCOUNT_TASK = "INSERT INTO accountTasks (accountId, taskId) VALUES (?, ?);"; + private static String RETRIEVE_TASKS = "SELECT id, name FROM tasks;"; + + private static Connection _connection; + + public ChestConverterRepository() + { + PreparedStatement preparedStatement = null; + + try + { + Class.forName("com.mysql.jdbc.Driver"); + + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public HashMap getTaskList() + { + HashMap tasks = new HashMap(); + PreparedStatement preparedStatement = null; + + try + { + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + preparedStatement = _connection.prepareStatement(RETRIEVE_TASKS); + preparedStatement.execute(); + + ResultSet resultSet = preparedStatement.getResultSet(); + + while (resultSet.next()) + { + tasks.put(resultSet.getString(2), resultSet.getInt(1)); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return tasks; + } + + public List getTasks(int lastId, int count) throws Exception + { + return new JsonWebCall("http://accounts.mineplex.com/PlayerAccount/GetTasksByCount").Execute(new com.google.gson.reflect.TypeToken>(){}.getType(), new SearchConf(lastId, count)); + } + + public void incrementClients(HashMap> playerList) + { + PreparedStatement preparedStatement = null; + Statement statement = null; + + try + { + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + statement = _connection.createStatement(); + HashMap> playerIdList = new HashMap>(); + String queryString = ""; + for (Entry> entry : playerList.entrySet()) + { + queryString += "SELECT id FROM accounts WHERE accounts.uuid = '" + entry.getKey() + "' LIMIT 1;"; + } + + statement.execute(queryString); + statement.getUpdateCount(); + + for (Entry> entry : playerList.entrySet()) + { + ResultSet resultSet = statement.getResultSet(); + + while (resultSet.next()) + { + for (Integer taskId : entry.getValue()) + { + if (!playerIdList.containsKey(resultSet.getInt(1))) + playerIdList.put(resultSet.getInt(1), new ArrayList()); + + playerIdList.get(resultSet.getInt(1)).add(taskId); + } + } + statement.getMoreResults(); + } + + preparedStatement = _connection.prepareStatement(ADD_ACCOUNT_TASK); + System.out.println("adding to mysql db."); + for (Entry> entry : playerIdList.entrySet()) + { + for (Integer taskId : entry.getValue()) + { + preparedStatement.setInt(1, entry.getKey()); + preparedStatement.setInt(2, taskId); + preparedStatement.addBatch(); + } + } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/GenericRunnable.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/GenericRunnable.java new file mode 100644 index 00000000..987c74db --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/GenericRunnable.java @@ -0,0 +1,6 @@ +package mineplex.chestConverter; + +public interface GenericRunnable +{ + void run(T t); +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/JsonWebCall.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/JsonWebCall.java new file mode 100644 index 00000000..2bfc6f76 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/JsonWebCall.java @@ -0,0 +1,349 @@ +package mineplex.chestConverter; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilSystem; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +public class JsonWebCall +{ + private String _url; + private PoolingClientConnectionManager _connectionManager; + + public JsonWebCall(String url) + { + _url = url; + + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + + _connectionManager = new PoolingClientConnectionManager(schemeRegistry); + _connectionManager.setMaxTotal(200); + _connectionManager.setDefaultMaxPerRoute(20); + } + + public String ExecuteReturnStream(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + result = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return result; + } + + public void Execute() + { + Execute((Object)null); + } + + public void Execute(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + + try + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + httpClient.execute(request); + } + catch (Exception ex) + { + System.out.println("JsonWebCall.Execute() Error:\n" + ex.getMessage()); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) throws Exception + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnType); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public T Execute(Class returnClass, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnClass); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public void Execute(Class callbackClass, Callback callback) + { + Execute(callbackClass, callback, (Object)null); + } + + public void Execute(Class callbackClass, Callback callback, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null && callback != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + callback.run(new Gson().fromJson(result, callbackClass)); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + UtilSystem.printStackTrace(ex.getStackTrace()); + System.out.println("Result: \n" + result); + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/SearchConf.java b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/SearchConf.java new file mode 100644 index 00000000..98fa721a --- /dev/null +++ b/Plugins[Modified]/Mineplex.ChestConverter/src/mineplex/chestConverter/SearchConf.java @@ -0,0 +1,13 @@ +package mineplex.chestConverter; + +public class SearchConf +{ + public SearchConf(int idIndex, int count) + { + IdIndex = idIndex; + Count = count; + } + + public int IdIndex; + public int Count; +} diff --git a/Plugins[Modified]/Mineplex.ClansGenerator/plugin.yml b/Plugins[Modified]/Mineplex.ClansGenerator/plugin.yml new file mode 100644 index 00000000..c04a3807 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansGenerator/plugin.yml @@ -0,0 +1,4 @@ +name: ClansGenerator +main: mineplex.clansgenerator.ClansGenerator +version: 1.0 +author: Alex \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansGenerator/pom.xml b/Plugins[Modified]/Mineplex.ClansGenerator/pom.xml new file mode 100644 index 00000000..655d4d4c --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansGenerator/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + ClansGenerator + mineplex-clansgenerator + + + + ${project.groupId} + mineplex-core-common + ${project.version} + + + diff --git a/Plugins[Modified]/Mineplex.ClansGenerator/src/mineplex/clansgenerator/ClansGenerator.java b/Plugins[Modified]/Mineplex.ClansGenerator/src/mineplex/clansgenerator/ClansGenerator.java new file mode 100644 index 00000000..2238167d --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansGenerator/src/mineplex/clansgenerator/ClansGenerator.java @@ -0,0 +1,198 @@ +package mineplex.clansgenerator; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ThreadLocalRandom; + +import org.apache.commons.io.FileUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.WorldCreator; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; +import org.bukkit.event.world.ChunkPopulateEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.spigotmc.WatchdogThread; + +import net.minecraft.server.v1_8_R3.BiomeBase; + +public class ClansGenerator extends JavaPlugin implements Runnable, Listener +{ + private static final int MIN_X = -100; + private static final int MIN_Z = -100; + private static final int MAX_X = 100; + private static final int MAX_Z = 100; + + private File _root; + private File _outputDir; + private boolean _debug = false; + + public void onEnable() + { + _root = new File("."); + if (!_root.exists()) + { + getLogger().severe("Root folder does not exist. Aborting"); + getServer().shutdown(); + return; + } + _outputDir = new File(_root, "output"); + if (new File(_root, "DEBUG.dat").exists()) + { + _debug = true; + } + if (!_outputDir.exists()) + { + if (_debug) + { + getLogger().info("Creating map output directory!"); + } + _outputDir.mkdir(); + } + BiomeBase.getBiomes()[BiomeBase.OCEAN.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.PLAINS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.DESERT.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.EXTREME_HILLS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.FOREST.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.TAIGA.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.SWAMPLAND.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.RIVER.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.HELL.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.SKY.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.FROZEN_OCEAN.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.FROZEN_RIVER.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.ICE_PLAINS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.ICE_MOUNTAINS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.MUSHROOM_ISLAND.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.MUSHROOM_SHORE.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.BEACH.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.DESERT_HILLS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.FOREST_HILLS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.TAIGA_HILLS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.SMALL_MOUNTAINS.id] = BiomeBase.PLAINS; + BiomeBase.getBiomes()[BiomeBase.JUNGLE.id] = BiomeBase.EXTREME_HILLS; + BiomeBase.getBiomes()[BiomeBase.JUNGLE_HILLS.id] = BiomeBase.EXTREME_HILLS; + BiomeBase.getBiomes()[BiomeBase.JUNGLE_EDGE.id] = BiomeBase.EXTREME_HILLS; + BiomeBase.getBiomes()[BiomeBase.DEEP_OCEAN.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.STONE_BEACH.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.COLD_BEACH.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.BIRCH_FOREST.id] = BiomeBase.BIRCH_FOREST; + BiomeBase.getBiomes()[BiomeBase.BIRCH_FOREST_HILLS.id] = BiomeBase.BIRCH_FOREST_HILLS; + BiomeBase.getBiomes()[BiomeBase.ROOFED_FOREST.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.COLD_TAIGA.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.COLD_TAIGA_HILLS.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.MEGA_TAIGA.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.MEGA_TAIGA_HILLS.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.EXTREME_HILLS_PLUS.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.SAVANNA.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.SAVANNA_PLATEAU.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.MESA.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.MESA_PLATEAU_F.id] = BiomeBase.FOREST; + BiomeBase.getBiomes()[BiomeBase.MESA_PLATEAU.id] = BiomeBase.FOREST; + WatchdogThread.doStop(); + getServer().getScheduler().runTaskTimer(this, this, 20L, 100L); + getServer().getPluginManager().registerEvents(this, this); + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onPopulate(ChunkPopulateEvent event) + { + Block block; + for (int x = 0; x < 16; x++) + { + for (int y = 1; y < 128; y++) + { + for (int z = 0; z < 16; z++) + { + block = event.getChunk().getBlock(x, y, z); + if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST || block.getType() == Material.MOB_SPAWNER) + { + block.setType(Material.AIR); + if (_debug) + { + getLogger().info("Removing dungeon pieces"); + } + continue; + } + if (block.getType() == Material.LAVA) + { + byte data = block.getData(); + block.setTypeIdAndData(Material.WATER.getId(), data, false); + if (_debug) + { + getLogger().info("Removing lava"); + } + continue; + } + if (block.getType() == Material.STATIONARY_LAVA) + { + byte data = block.getData(); + block.setTypeIdAndData(Material.STATIONARY_WATER.getId(), data, false); + if (_debug) + { + getLogger().info("Removing lava"); + } + continue; + } + } + } + } + } + + @EventHandler + public void onJoin(AsyncPlayerPreLoginEvent event) + { + event.setLoginResult(Result.KICK_OTHER); + event.setKickMessage("Shoo, go away"); + } + + public void run() + { + int nextFileId = 0; + for (int existingFiles = 0; new File(_outputDir, "Clans_Map_" + existingFiles).exists(); existingFiles++) + { + nextFileId++; + } + + getLogger().info("Generating world id " + nextFileId); + World world = (new WorldCreator("Clans_Map_" + nextFileId)).environment(Environment.NORMAL).generateStructures(false).seed(ThreadLocalRandom.current().nextLong()).createWorld(); + world.setKeepSpawnInMemory(false); + for (int x = MIN_X; x <= MAX_X; x++) + { + getLogger().info("Generating chunks for x coord " + x); + for (int z = MIN_Z; z <= MAX_Z; z++) + { + world.getChunkAt(x, z).load(true); + } + } + + for (int x = MIN_X; x <= MAX_X; x++) + { + getLogger().info("Unloading chunks for x coord " + x); + for (int z = MIN_Z; z <= MAX_Z; z++) + { + world.getChunkAt(x, z).unload(true, false); + } + } + + getLogger().info("Unloading and saving world"); + Bukkit.unloadWorld(world, true); + getLogger().info("Finished unloading and saving world"); + try + { + FileUtils.moveDirectoryToDirectory(new File(_root, "Clans_Map_" + nextFileId), _outputDir, false); + } + catch (IOException e) + { + e.printStackTrace(); + } + getLogger().info("Finished generating world id " + nextFileId); + getServer().shutdown(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/pom.xml b/Plugins[Modified]/Mineplex.ClansQueue.Common/pom.xml new file mode 100644 index 00000000..10f7c455 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.mineplex + mineplex-parent + dev-SNAPSHOT + ../pom.xml + + + ClansQueue-Common + mineplex-clansqueue-common + + + + ${project.groupId} + mineplex-serverdata + ${project.version} + + + diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessage.java new file mode 100644 index 00000000..2bb7211c --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessage.java @@ -0,0 +1,8 @@ +package com.mineplex.clansqueue.common; + +public class ClansQueueMessage +{ + protected String Origin; + protected String BodyClass; + protected String BodySerialized; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessageBody.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessageBody.java new file mode 100644 index 00000000..7c739f16 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessageBody.java @@ -0,0 +1,12 @@ +package com.mineplex.clansqueue.common; + +import mineplex.serverdata.Utility; + +public abstract class ClansQueueMessageBody +{ + @Override + public final String toString() + { + return Utility.serialize(this); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessenger.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessenger.java new file mode 100644 index 00000000..1de841e9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/ClansQueueMessenger.java @@ -0,0 +1,115 @@ +package com.mineplex.clansqueue.common; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; + +import mineplex.serverdata.Utility; +import mineplex.serverdata.servers.ServerManager; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPubSub; + +public class ClansQueueMessenger +{ + private static final String CHANNEL_NAME_BASE = "ClansQueueMessageChannel:"; + + private static final Map _messengers = new ConcurrentHashMap<>(); + + private final String _identifier; + private final JedisPool _readPool; + private final JedisPool _writePool; + @SuppressWarnings("rawtypes") + private final Map _bodyTypes = Collections.synchronizedMap(new HashMap<>()); + @SuppressWarnings("rawtypes") + private final Map> _listeners = Collections.synchronizedMap(new HashMap<>()); + + private ClansQueueMessenger(String identifier) + { + _identifier = identifier; + + _writePool = Utility.generatePool(ServerManager.getMasterConnection()); + _readPool = Utility.generatePool(ServerManager.getSlaveConnection()); + + initialize(); + } + + private void initialize() + { + new Thread("Clans Queue Messenger: " + _identifier) + { + public void run() + { + try (Jedis jedis = _readPool.getResource()) + { + jedis.subscribe(new ClansQueueMessageListener(ClansQueueMessenger.this), CHANNEL_NAME_BASE + "ALL", CHANNEL_NAME_BASE + _identifier); + } + } + }.start(); + } + + public void registerListener(Class messageType, BiConsumer callback) + { + _bodyTypes.putIfAbsent(messageType.getName(), messageType); + _listeners.computeIfAbsent(messageType.getName(), (type) -> new ArrayList<>()).add(callback); + } + + public void transmitMessage(ClansQueueMessageBody message) + { + transmitMessage(message, "ALL"); + } + + public void transmitMessage(ClansQueueMessageBody message, String target) + { + ClansQueueMessage msg = new ClansQueueMessage(); + msg.Origin = _identifier; + msg.BodyClass = message.getClass().getName(); + msg.BodySerialized = message.toString(); + + final String toSend = Utility.serialize(msg); + + new Thread(() -> + { + try (Jedis jedis = _writePool.getResource()) + { + jedis.publish(CHANNEL_NAME_BASE + target, toSend); + } + }).start(); + } + + @SuppressWarnings("unchecked") + public void receiveMessage(ClansQueueMessage message) + { + if (_listeners.containsKey(message.BodyClass) && _bodyTypes.containsKey(message.BodyClass)) + { + T body = Utility.deserialize(message.BodySerialized, (Class)_bodyTypes.get(message.BodyClass)); + _listeners.get(message.BodyClass).forEach(listener -> listener.accept(body, message.Origin)); + } + } + + private static class ClansQueueMessageListener extends JedisPubSub + { + private final ClansQueueMessenger _manager; + + private ClansQueueMessageListener(ClansQueueMessenger manager) + { + _manager = manager; + } + + @Override + public void onMessage(String channelName, String message) + { + ClansQueueMessage msg = Utility.deserialize(message, ClansQueueMessage.class); + _manager.receiveMessage(msg); + } + } + + public static ClansQueueMessenger getMessenger(String identifier) + { + return _messengers.computeIfAbsent(identifier, (id) -> new ClansQueueMessenger(id)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/EnclosedInteger.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/EnclosedInteger.java new file mode 100644 index 00000000..4e079161 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/EnclosedInteger.java @@ -0,0 +1,39 @@ +package com.mineplex.clansqueue.common; + +import javax.annotation.concurrent.NotThreadSafe; + +@NotThreadSafe +public class EnclosedInteger +{ + private int _value; + + public EnclosedInteger(int value) + { + _value = value; + } + + public EnclosedInteger() + { + this(0); + } + + public int get() + { + return _value; + } + + public int getAndIncrement() + { + return _value++; + } + + public int incrementAndGet() + { + return ++_value; + } + + public void set(int newValue) + { + _value = newValue; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/QueueConstant.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/QueueConstant.java new file mode 100644 index 00000000..9be7e93e --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/QueueConstant.java @@ -0,0 +1,12 @@ +package com.mineplex.clansqueue.common; + +import java.util.concurrent.TimeUnit; + +public class QueueConstant +{ + public static final String SERVICE_MESSENGER_IDENTIFIER = "Queue System"; + public static final int BYPASS_QUEUE_WEIGHT = -1; + public static final int MAX_TRANSFERS_PER_UPDATE = 5; + public static final int MAXIMUM_WEIGHT_FROM_INCREASE = 6; + public static final long TIME_TO_INCREASE_WEIGHT = TimeUnit.MINUTES.toMillis(10); +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/SortableLinkedList.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/SortableLinkedList.java new file mode 100644 index 00000000..2b1bda0a --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/SortableLinkedList.java @@ -0,0 +1,13 @@ +package com.mineplex.clansqueue.common; + +import java.util.Comparator; +import java.util.LinkedList; + +@SuppressWarnings("serial") +public class SortableLinkedList> extends LinkedList +{ + public void sort() + { + sort(Comparator.naturalOrder()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ClansServerStatusMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ClansServerStatusMessage.java new file mode 100644 index 00000000..f8e0d711 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ClansServerStatusMessage.java @@ -0,0 +1,10 @@ +package com.mineplex.clansqueue.common.messages; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class ClansServerStatusMessage extends ClansQueueMessageBody +{ + public String ServerName; + public int OpenSlots; + public boolean Online; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerJoinQueueCallbackMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerJoinQueueCallbackMessage.java new file mode 100644 index 00000000..73fa9323 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerJoinQueueCallbackMessage.java @@ -0,0 +1,12 @@ +package com.mineplex.clansqueue.common.messages; + +import java.util.UUID; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class PlayerJoinQueueCallbackMessage extends ClansQueueMessageBody +{ + public UUID PlayerUUID; + public String TargetServer; + public int Position; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerJoinQueueMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerJoinQueueMessage.java new file mode 100644 index 00000000..c3194629 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerJoinQueueMessage.java @@ -0,0 +1,12 @@ +package com.mineplex.clansqueue.common.messages; + +import java.util.UUID; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class PlayerJoinQueueMessage extends ClansQueueMessageBody +{ + public UUID PlayerUUID; + public String TargetServer; + public int PlayerPriority; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerLeaveQueueMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerLeaveQueueMessage.java new file mode 100644 index 00000000..dc177c45 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerLeaveQueueMessage.java @@ -0,0 +1,11 @@ +package com.mineplex.clansqueue.common.messages; + +import java.util.UUID; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class PlayerLeaveQueueMessage extends ClansQueueMessageBody +{ + public UUID PlayerUUID; + public String TargetServer; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerSendToServerMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerSendToServerMessage.java new file mode 100644 index 00000000..b1fe5fff --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/PlayerSendToServerMessage.java @@ -0,0 +1,11 @@ +package com.mineplex.clansqueue.common.messages; + +import java.util.UUID; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class PlayerSendToServerMessage extends ClansQueueMessageBody +{ + public UUID PlayerUUID; + public String TargetServer; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueueDeleteMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueueDeleteMessage.java new file mode 100644 index 00000000..d8594724 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueueDeleteMessage.java @@ -0,0 +1,8 @@ +package com.mineplex.clansqueue.common.messages; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class QueueDeleteMessage extends ClansQueueMessageBody +{ + public String ServerName; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueuePauseBroadcastMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueuePauseBroadcastMessage.java new file mode 100644 index 00000000..b871ee25 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueuePauseBroadcastMessage.java @@ -0,0 +1,9 @@ +package com.mineplex.clansqueue.common.messages; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class QueuePauseBroadcastMessage extends ClansQueueMessageBody +{ + public String ServerName; + public boolean Paused; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueuePauseUpdateMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueuePauseUpdateMessage.java new file mode 100644 index 00000000..c1706444 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueuePauseUpdateMessage.java @@ -0,0 +1,9 @@ +package com.mineplex.clansqueue.common.messages; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class QueuePauseUpdateMessage extends ClansQueueMessageBody +{ + public String ServerName; + public boolean Paused; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueueStatusMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueueStatusMessage.java new file mode 100644 index 00000000..135acb4c --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/QueueStatusMessage.java @@ -0,0 +1,20 @@ +package com.mineplex.clansqueue.common.messages; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class QueueStatusMessage extends ClansQueueMessageBody +{ + public final List Snapshots = new ArrayList<>(); + + public static class QueueSnapshot + { + public String ServerName; + public Map Queue; + public boolean Paused; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ServerOfflineMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ServerOfflineMessage.java new file mode 100644 index 00000000..51761ccb --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ServerOfflineMessage.java @@ -0,0 +1,8 @@ +package com.mineplex.clansqueue.common.messages; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class ServerOfflineMessage extends ClansQueueMessageBody +{ + public String ServerName; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ServerOnlineMessage.java b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ServerOnlineMessage.java new file mode 100644 index 00000000..0d95cc1a --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue.Common/src/com/mineplex/clansqueue/common/messages/ServerOnlineMessage.java @@ -0,0 +1,8 @@ +package com.mineplex.clansqueue.common.messages; + +import com.mineplex.clansqueue.common.ClansQueueMessageBody; + +public class ServerOnlineMessage extends ClansQueueMessageBody +{ + public String ServerName; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/pom.xml b/Plugins[Modified]/Mineplex.ClansQueue/pom.xml new file mode 100644 index 00000000..a202846c --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + ClansQueue + mineplex-clansqueue + + + + ${project.groupId} + mineplex-clansqueue-common + ${project.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + + false + + + com.mineplex.clansqueue.service.QueueService + + + + + + package + + shade + + + + + + + diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/QueueService.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/QueueService.java new file mode 100644 index 00000000..433af8c1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/QueueService.java @@ -0,0 +1,93 @@ +package com.mineplex.clansqueue.service; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.mineplex.clansqueue.common.ClansQueueMessenger; +import com.mineplex.clansqueue.common.QueueConstant; +import com.mineplex.clansqueue.common.messages.ClansServerStatusMessage; +import com.mineplex.clansqueue.common.messages.PlayerJoinQueueMessage; +import com.mineplex.clansqueue.common.messages.PlayerLeaveQueueMessage; +import com.mineplex.clansqueue.common.messages.QueuePauseUpdateMessage; +import com.mineplex.clansqueue.common.messages.ServerOfflineMessage; +import com.mineplex.clansqueue.common.messages.ServerOnlineMessage; +import com.mineplex.clansqueue.service.commands.CommandSystem; +import com.mineplex.clansqueue.service.commands.ConsoleCommand; +import com.mineplex.clansqueue.service.queue.ClansQueueManager; + +import mineplex.serverdata.Region; + +public class QueueService +{ + public static void main(String[] args) + { + QueueService service = new QueueService(new File("eu.dat").exists()); + service.start(); + while (service.isRunning()) {} + System.exit(0); + } + + private final Region _region; + private boolean _running = false; + private final Map _commandMap = Collections.synchronizedMap(new HashMap<>()); + private final CommandSystem _commandSystem; + private final ClansQueueManager _queueManager; + + private QueueService(boolean eu) + { + if (eu) + { + _region = Region.EU; + } + else + { + _region = Region.US; + } + _commandSystem = new CommandSystem(this, _commandMap); + _queueManager = new ClansQueueManager(this); + } + + private synchronized void start() + { + System.out.println("[Queue Service] Enabling on region " + getRegion().name()); + _running = true; + _commandSystem.start(); + + ClansQueueMessenger messenger = ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + messenger.registerListener(ServerOnlineMessage.class, (online, origin) -> _queueManager.handleServerEnable(online.ServerName)); + messenger.registerListener(ServerOfflineMessage.class, (offline, origin) -> _queueManager.handleServerDisable(offline.ServerName)); + messenger.registerListener(QueuePauseUpdateMessage.class, (pause, origin) -> _queueManager.handleQueuePause(pause.ServerName, pause.Paused)); + messenger.registerListener(PlayerJoinQueueMessage.class, (join, origin) -> _queueManager.joinQueue(join.TargetServer, origin, join.PlayerUUID, join.PlayerPriority)); + messenger.registerListener(PlayerLeaveQueueMessage.class, (leave, origin) -> _queueManager.leaveQueue(leave.TargetServer, leave.PlayerUUID)); + messenger.registerListener(ClansServerStatusMessage.class, (status, origin) -> _queueManager.handleServerUpdate(status.ServerName, status.OpenSlots, status.Online)); + } + + public ClansQueueManager getQueueManager() + { + return _queueManager; + } + + public synchronized boolean isRunning() + { + return _running; + } + + public Region getRegion() + { + return _region; + } + + public void registerCommand(ConsoleCommand command) + { + _commandMap.put(command.getCommand().toLowerCase(), command); + } + + public synchronized void shutdown() + { + System.out.println("[Queue Service] Shutting down..."); + _queueManager.stop(); + _running = false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/CommandSystem.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/CommandSystem.java new file mode 100644 index 00000000..e0240963 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/CommandSystem.java @@ -0,0 +1,65 @@ +package com.mineplex.clansqueue.service.commands; + +import java.util.Map; +import java.util.Optional; +import java.util.Scanner; + +import com.mineplex.clansqueue.service.QueueService; + +public class CommandSystem extends Thread +{ + private final QueueService _service; + private final Map _commands; + + public CommandSystem(QueueService service, Map commands) + { + super("Command System"); + _service = service; + _commands = commands; + + _service.registerCommand(new HelpCommand(_commands)); + _service.registerCommand(new StopCommand(_service)); + _service.registerCommand(new DeleteQueueCommand(_service)); + _service.registerCommand(new ListQueuesCommand(_service)); + _service.registerCommand(new PauseQueueCommand(_service)); + _service.registerCommand(new UnpauseQueueCommand(_service)); + } + + private boolean matches(String key, String input) + { + if (key.equalsIgnoreCase(input)) + { + return true; + } + if (input.toLowerCase().startsWith(key + " ")) + { + return true; + } + return false; + } + + @Override + public void run() + { + try (Scanner scanner = new Scanner(System.in)) + { + while (_service.isRunning()) + { + String input = scanner.nextLine(); + if (input.isEmpty()) + { + continue; + } + Optional opt = _commands.entrySet().stream().filter(entry -> matches(entry.getKey(), input)).map(Map.Entry::getValue).findAny(); + if (opt.isPresent()) + { + opt.get().call(input); + } + else + { + System.out.println("Command '" + input.split(" ")[0] + "' was not found. Run 'help' for a list of commands."); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/ConsoleCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/ConsoleCommand.java new file mode 100644 index 00000000..f962d4dd --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/ConsoleCommand.java @@ -0,0 +1,59 @@ +package com.mineplex.clansqueue.service.commands; + +public abstract class ConsoleCommand +{ + private final String _command; + private final String _usageText; + private StringBuilder _outputBuilder; + + public ConsoleCommand(String command, String usageText) + { + _command = command; + _usageText = usageText; + } + + public String getCommand() + { + return _command; + } + + public String getUsageText() + { + return _usageText; + } + + protected final void addOutput(String text) + { + if (_outputBuilder == null) + { + _outputBuilder = new StringBuilder(); + } + else + { + _outputBuilder.append("\n"); + } + _outputBuilder.append(text); + } + + protected final void sendOutput() + { + System.out.println(_outputBuilder.toString()); + _outputBuilder = null; + } + + public final void call(String input) + { + String parsing = input.trim(); + if (parsing.length() > getCommand().length() + 2) + { + String[] args = parsing.substring(getCommand().length() + 1).split(" "); + use(args); + } + else + { + use(new String[] {}); + } + } + + protected abstract void use(String[] arguments); +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/DeleteQueueCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/DeleteQueueCommand.java new file mode 100644 index 00000000..fd169d08 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/DeleteQueueCommand.java @@ -0,0 +1,38 @@ +package com.mineplex.clansqueue.service.commands; + +import com.mineplex.clansqueue.service.QueueService; +import com.mineplex.clansqueue.service.queue.ClansServer; + +public class DeleteQueueCommand extends ConsoleCommand +{ + private final QueueService _service; + + public DeleteQueueCommand(QueueService service) + { + super("delete", "Deletes an existing server and queue"); + + _service = service; + } + + @Override + protected void use(String[] arguments) + { + if (arguments.length < 1) + { + addOutput("Usage: delete "); + sendOutput(); + return; + } + ClansServer server = _service.getQueueManager().getLoadedServer(arguments[0]); + if (server == null) + { + addOutput("Server '" + arguments[0] + "' was not found. Run 'list' for a list of servers."); + sendOutput(); + return; + } + + _service.getQueueManager().deleteServer(server); + addOutput("Server and queue deleted."); + sendOutput(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/HelpCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/HelpCommand.java new file mode 100644 index 00000000..808c1ab2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/HelpCommand.java @@ -0,0 +1,41 @@ +package com.mineplex.clansqueue.service.commands; + +import java.util.Map; + +public class HelpCommand extends ConsoleCommand +{ + private final Map _commands; + + public HelpCommand(Map commands) + { + super("help", "Lists commands and their usage"); + + _commands = commands; + } + + @Override + protected void use(String[] arguments) + { + if (arguments.length < 1) + { + addOutput("Commands:"); + _commands.values().forEach(command -> + { + addOutput(command.getCommand() + " : " + command.getUsageText()); + }); + } + else + { + if (_commands.containsKey(arguments[0].toLowerCase())) + { + ConsoleCommand cmd = _commands.get(arguments[0].toLowerCase()); + addOutput(cmd.getCommand() + " : " + cmd.getUsageText()); + } + else + { + addOutput("Command '" + arguments[0] + "' was not found. Run 'help' for a list of commands."); + } + } + sendOutput(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/ListQueuesCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/ListQueuesCommand.java new file mode 100644 index 00000000..55de6784 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/ListQueuesCommand.java @@ -0,0 +1,29 @@ +package com.mineplex.clansqueue.service.commands; + +import java.util.stream.Collectors; + +import com.mineplex.clansqueue.service.QueueService; +import com.mineplex.clansqueue.service.queue.ClansServer; + +public class ListQueuesCommand extends ConsoleCommand +{ + private final QueueService _service; + + public ListQueuesCommand(QueueService service) + { + super("list", "Lists existing servers"); + + _service = service; + } + + @Override + protected void use(String[] arguments) + { + StringBuilder servers = new StringBuilder("Servers: ["); + servers.append(_service.getQueueManager().getLoadedServers().stream().map(ClansServer::getName).collect(Collectors.joining(", "))); + servers.append(']'); + + addOutput(servers.toString()); + sendOutput(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/PauseQueueCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/PauseQueueCommand.java new file mode 100644 index 00000000..c417883e --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/PauseQueueCommand.java @@ -0,0 +1,38 @@ +package com.mineplex.clansqueue.service.commands; + +import com.mineplex.clansqueue.service.QueueService; +import com.mineplex.clansqueue.service.queue.ClansServer; + +public class PauseQueueCommand extends ConsoleCommand +{ + private final QueueService _service; + + public PauseQueueCommand(QueueService service) + { + super("pause", "Pauses an existing queue"); + + _service = service; + } + + @Override + protected void use(String[] arguments) + { + if (arguments.length < 1) + { + addOutput("Usage: pause "); + sendOutput(); + return; + } + ClansServer server = _service.getQueueManager().getLoadedServer(arguments[0]); + if (server == null) + { + addOutput("Server '" + arguments[0] + "' was not found. Run 'list' for a list of servers."); + sendOutput(); + return; + } + + _service.getQueueManager().handleQueuePause(server.getName(), true); + addOutput("Queue paused."); + sendOutput(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/StopCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/StopCommand.java new file mode 100644 index 00000000..a1c100d6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/StopCommand.java @@ -0,0 +1,21 @@ +package com.mineplex.clansqueue.service.commands; + +import com.mineplex.clansqueue.service.QueueService; + +public class StopCommand extends ConsoleCommand +{ + private final QueueService _service; + + public StopCommand(QueueService service) + { + super("stop", "Stops the Queue Service"); + + _service = service; + } + + @Override + protected void use(String[] arguments) + { + _service.shutdown(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/UnpauseQueueCommand.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/UnpauseQueueCommand.java new file mode 100644 index 00000000..c047e697 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/commands/UnpauseQueueCommand.java @@ -0,0 +1,38 @@ +package com.mineplex.clansqueue.service.commands; + +import com.mineplex.clansqueue.service.QueueService; +import com.mineplex.clansqueue.service.queue.ClansServer; + +public class UnpauseQueueCommand extends ConsoleCommand +{ + private final QueueService _service; + + public UnpauseQueueCommand(QueueService service) + { + super("unpause", "Resumes an existing queue"); + + _service = service; + } + + @Override + protected void use(String[] arguments) + { + if (arguments.length < 1) + { + addOutput("Usage: unpause "); + sendOutput(); + return; + } + ClansServer server = _service.getQueueManager().getLoadedServer(arguments[0]); + if (server == null) + { + addOutput("Server '" + arguments[0] + "' was not found. Run 'list' for a list of servers."); + sendOutput(); + return; + } + + _service.getQueueManager().handleQueuePause(server.getName(), false); + addOutput("Queue unpaused."); + sendOutput(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ClansQueueManager.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ClansQueueManager.java new file mode 100644 index 00000000..ce0d765d --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ClansQueueManager.java @@ -0,0 +1,198 @@ +package com.mineplex.clansqueue.service.queue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import com.mineplex.clansqueue.common.ClansQueueMessenger; +import com.mineplex.clansqueue.common.QueueConstant; +import com.mineplex.clansqueue.common.messages.PlayerJoinQueueCallbackMessage; +import com.mineplex.clansqueue.common.messages.PlayerSendToServerMessage; +import com.mineplex.clansqueue.common.messages.QueueDeleteMessage; +import com.mineplex.clansqueue.common.messages.QueuePauseBroadcastMessage; +import com.mineplex.clansqueue.common.messages.QueueStatusMessage; +import com.mineplex.clansqueue.common.messages.QueueStatusMessage.QueueSnapshot; +import com.mineplex.clansqueue.service.QueueService; + +public class ClansQueueManager +{ + private final Map _servers = new HashMap<>(); + private final Map _queues = new HashMap<>(); + private final ScheduledFuture _updater; + + public ClansQueueManager(QueueService service) + { + _updater = Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() -> + { + if (service.isRunning()) + { + updateQueues(); + } + }, 0, 5, TimeUnit.SECONDS); + } + + private QueueStatusMessage buildStatusMessage(Collection queues) + { + QueueStatusMessage message = new QueueStatusMessage(); + + queues.forEach(queue -> + { + QueueSnapshot snapshot = new QueueSnapshot(); + snapshot.Paused = queue.isPaused(); + snapshot.ServerName = queue.getServer().getName(); + snapshot.Queue = new HashMap<>(); + queue.getPlayers().values().forEach(player -> snapshot.Queue.put(player.PlayerUUID, player.Position)); + + message.Snapshots.add(snapshot); + }); + + return message; + } + + private synchronized void updateQueues() + { + System.out.println("Updating queues"); + Collection queues = _queues.values(); + + queues.forEach(q -> + { + q.updatePositions(Math.min(q.getServer().getOpenSlots(), QueueConstant.MAX_TRANSFERS_PER_UPDATE)); + if (q.getServer().isOnline()) + { + q.getNextSend().entrySet().forEach(entry -> + { + PlayerSendToServerMessage message = new PlayerSendToServerMessage(); + message.PlayerUUID = entry.getKey(); + message.TargetServer = q.getServer().getName(); + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(message, entry.getValue()); + }); + } + }); + + QueueStatusMessage message = buildStatusMessage(queues); + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(message); + } + + public synchronized ClansServer getLoadedServer(String serverName) + { + return _servers.get(serverName); + } + + public synchronized Collection getLoadedServers() + { + return Collections.unmodifiableCollection(_servers.values()); + } + + public synchronized void deleteServer(ClansServer server) + { + _servers.remove(server.getName()); + _queues.remove(server); + QueueDeleteMessage message = new QueueDeleteMessage(); + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(message); + } + + public synchronized void handleServerEnable(String serverName) + { + _servers.computeIfAbsent(serverName, (name) -> + { + ClansServer server = new ClansServer(name); + + _queues.put(server, new ServerQueue(server)); + + return server; + }).setOnline(true); + + System.out.println("Clans server " + serverName + " enabled."); + } + + public synchronized void handleServerDisable(String serverName) + { + _servers.computeIfAbsent(serverName, (name) -> + { + ClansServer server = new ClansServer(name); + + _queues.put(server, new ServerQueue(server)); + + return server; + }).setOnline(false); + } + + public synchronized void handleServerUpdate(String serverName, int openSlots, boolean online) + { + ClansServer server = _servers.computeIfAbsent(serverName, (name) -> + { + ClansServer s = new ClansServer(name); + + _queues.put(s, new ServerQueue(s)); + + return s; + }); + server.setOpenSlots(openSlots); + server.setOnline(online); + } + + public synchronized void handleQueuePause(String serverName, boolean pause) + { + ClansServer server = _servers.get(serverName); + if (server != null) + { + _queues.get(server).setPaused(pause); + System.out.println("Clans server " + serverName + " queue pause: " + pause); + QueuePauseBroadcastMessage message = new QueuePauseBroadcastMessage(); + message.ServerName = serverName; + message.Paused = pause; + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(message); + } + } + + public synchronized void joinQueue(String serverName, String currentServer, UUID uuid, int weight) + { + ClansServer server = _servers.get(serverName); + if (server != null) + { + ServerQueue queue = _queues.get(server); + if (weight == QueueConstant.BYPASS_QUEUE_WEIGHT) + { + queue.addBypasser(uuid, currentServer); + } + else + { + queue.addPlayer(uuid, currentServer, weight, player -> + { + PlayerJoinQueueCallbackMessage message = new PlayerJoinQueueCallbackMessage(); + message.PlayerUUID = uuid; + message.TargetServer = serverName; + message.Position = player.Position; + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(message, currentServer); + QueueStatusMessage update = buildStatusMessage(Arrays.asList(queue)); + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(update); + }); + } + } + } + + public synchronized void leaveQueue(String serverName, UUID uuid) + { + ClansServer server = _servers.get(serverName); + if (server != null) + { + ServerQueue queue = _queues.get(server); + queue.removePlayer(uuid, () -> + { + QueueStatusMessage message = buildStatusMessage(Arrays.asList(queue)); + ClansQueueMessenger.getMessenger(QueueConstant.SERVICE_MESSENGER_IDENTIFIER).transmitMessage(message); + }); + } + } + + public void stop() + { + _updater.cancel(true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ClansServer.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ClansServer.java new file mode 100644 index 00000000..945cdd29 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ClansServer.java @@ -0,0 +1,63 @@ +package com.mineplex.clansqueue.service.queue; + +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; + +@ThreadSafe +public class ClansServer +{ + private final String _serverName; + + @GuardedBy("this") + private boolean _online = false; + + @GuardedBy("this") + private int _openSlots = 0; + + public ClansServer(String serverName) + { + _serverName = serverName; + } + + public String getName() + { + return _serverName; + } + + public synchronized boolean isOnline() + { + return _online; + } + + public synchronized void setOnline(boolean online) + { + _online = online; + } + + public synchronized int getOpenSlots() + { + return _openSlots; + } + + public synchronized void setOpenSlots(int openSlots) + { + _openSlots = openSlots; + } + + @Override + public int hashCode() + { + return _serverName.hashCode(); + } + + @Override + public boolean equals(Object o) + { + if (o == null || !getClass().isInstance(o)) + { + return false; + } + + return ((ClansServer)o)._serverName.equals(_serverName); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/QueuePlayer.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/QueuePlayer.java new file mode 100644 index 00000000..b2919280 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/QueuePlayer.java @@ -0,0 +1,97 @@ +package com.mineplex.clansqueue.service.queue; + +import java.util.UUID; + +import javax.annotation.concurrent.Immutable; +import javax.annotation.concurrent.NotThreadSafe; + +import com.google.common.base.Preconditions; +import com.mineplex.clansqueue.common.QueueConstant; + +@NotThreadSafe +public class QueuePlayer implements Comparable +{ + public final UUID PlayerUUID; + public final String CurrentServer; + public final long EntryTime; + public int Weight; + public long LastWeightIncrease; + public int Position; + + public QueuePlayer(UUID uuid, String currentServer, int weight) + { + PlayerUUID = uuid; + CurrentServer = currentServer; + EntryTime = System.currentTimeMillis(); + Weight = weight; + LastWeightIncrease = System.currentTimeMillis(); + } + + private void updateWeight() + { + if (Weight < QueueConstant.MAXIMUM_WEIGHT_FROM_INCREASE && (LastWeightIncrease + QueueConstant.TIME_TO_INCREASE_WEIGHT) < System.currentTimeMillis()) + { + Weight++; + LastWeightIncrease = System.currentTimeMillis(); + } + } + + public ImmutableQueuePlayer immutable() + { + return new ImmutableQueuePlayer(PlayerUUID, CurrentServer, Position); + } + + @Override + public int hashCode() + { + return PlayerUUID.hashCode(); + } + + @Override + public boolean equals(Object o) + { + if (o == null || !getClass().isInstance(o)) + { + return false; + } + + return ((QueuePlayer)o).PlayerUUID.equals(PlayerUUID); + } + + @Override + public int compareTo(QueuePlayer player) + { + Preconditions.checkNotNull(player); + + updateWeight(); + player.updateWeight(); + + if (Weight == player.Weight) + { + return Long.compare(EntryTime, player.EntryTime); + } + else if (Weight > player.Weight) + { + return -1; + } + else + { + return 1; + } + } + + @Immutable + public static class ImmutableQueuePlayer + { + public final UUID PlayerUUID; + public final String CurrentServer; + public final int Position; + + private ImmutableQueuePlayer(UUID uuid, String server, int position) + { + PlayerUUID = uuid; + CurrentServer = server; + Position = position; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ServerQueue.java b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ServerQueue.java new file mode 100644 index 00000000..9446a80d --- /dev/null +++ b/Plugins[Modified]/Mineplex.ClansQueue/src/com/mineplex/clansqueue/service/queue/ServerQueue.java @@ -0,0 +1,180 @@ +package com.mineplex.clansqueue.service.queue; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Consumer; + +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; + +import com.mineplex.clansqueue.common.EnclosedInteger; +import com.mineplex.clansqueue.common.SortableLinkedList; +import com.mineplex.clansqueue.service.queue.QueuePlayer.ImmutableQueuePlayer; + +@ThreadSafe +public class ServerQueue +{ + private final ClansServer _server; + + @GuardedBy("_sendLock") + private final Map _sending = new LinkedHashMap<>(); + + @GuardedBy("_bypassLock") + private final Map _bypassing = new LinkedHashMap<>(); + + @GuardedBy("_queueLock") + private final SortableLinkedList _queued = new SortableLinkedList<>(); + + private final Object _bypassLock = new Object(); + private final Object _queueLock = new Object(); + private final Object _sendLock = new Object(); + private final Object _pauseLock = new Object(); + + @GuardedBy("_pauseLock") + private boolean _paused = false; + + public ServerQueue(ClansServer server) + { + _server = server; + } + + private void sortQueue() + { + synchronized (_queueLock) + { + _queued.sort(); + EnclosedInteger position = new EnclosedInteger(1); + _queued.forEach(qp -> + { + qp.Position = position.getAndIncrement(); + }); + } + } + + public ClansServer getServer() + { + return _server; + } + + public boolean isPaused() + { + if (!_server.isOnline()) + { + return true; + } + + synchronized (_pauseLock) + { + return _paused; + } + } + + public Map getNextSend() + { + synchronized (_sendLock) + { + Map sending = new LinkedHashMap<>(); + sending.putAll(_sending); + _sending.clear(); + return sending; + } + } + + public Map getPlayers() + { + synchronized (_queueLock) + { + Map players = new LinkedHashMap<>(); + sortQueue(); + _queued.forEach(qp -> players.put(qp.PlayerUUID, qp.immutable())); + + return players; + } + } + + public void addBypasser(UUID uuid, String currentServer) + { + synchronized (_bypassLock) + { + _bypassing.put(uuid, currentServer); + } + } + + public void addPlayer(UUID uuid, String currentServer, int weight, Consumer callback) + { + synchronized (_queueLock) + { + QueuePlayer player = new QueuePlayer(uuid, currentServer, weight); + _queued.add(player); + + sortQueue(); + + if (callback != null) + { + callback.accept(player); + } + } + } + + public void removePlayer(UUID uuid, Runnable after) + { + synchronized (_queueLock) + { + _queued.removeIf(player -> player.PlayerUUID.equals(uuid)); + + sortQueue(); + + if (after != null) + { + after.run(); + } + } + } + + public void setPaused(boolean paused) + { + synchronized (_pauseLock) + { + _paused = paused; + } + } + + public void updatePositions(int openPlayerSlots) + { + Map send = new LinkedHashMap<>(); + if (_server.isOnline()) + { + synchronized (_bypassLock) + { + send.putAll(_bypassing); + _bypassing.clear(); + } + } + synchronized (_queueLock) + { + if (!isPaused() && openPlayerSlots > 0) + { + sortQueue(); + while (send.size() < openPlayerSlots) + { + QueuePlayer player = _queued.poll(); + if (player == null) + { + break; + } + send.put(player.PlayerUUID, player.CurrentServer); + } + sortQueue(); + } + } + if (send.isEmpty()) + { + return; + } + synchronized (_sendLock) + { + _sending.putAll(send); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Core.Common.Base/pom.xml b/Plugins[Modified]/Mineplex.Core.Common.Base/pom.xml index 0e57ec39..e3697fb8 100644 --- a/Plugins[Modified]/Mineplex.Core.Common.Base/pom.xml +++ b/Plugins[Modified]/Mineplex.Core.Common.Base/pom.xml @@ -13,14 +13,8 @@ - com.google.guava - guava - 23.0 - compile - - - com.labalityowo - spigot + org.spigotmc + spigot-api diff --git a/Plugins[Modified]/Mineplex.Core.Common/pom.xml b/Plugins[Modified]/Mineplex.Core.Common/pom.xml index 469b5fbf..cac13aef 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/pom.xml +++ b/Plugins[Modified]/Mineplex.Core.Common/pom.xml @@ -1,3 +1,4 @@ + 4.0.0 @@ -12,7 +13,7 @@ - com.labalityowo + com.mineplex spigot 1.0 @@ -35,7 +36,6 @@ - ${project.basedir} ascii.png diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/com/java/sk89q/jnbt/NBTUtils.java b/Plugins[Modified]/Mineplex.Core.Common/src/com/java/sk89q/jnbt/NBTUtils.java index 613bb78a..8e0b2d58 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/com/java/sk89q/jnbt/NBTUtils.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/com/java/sk89q/jnbt/NBTUtils.java @@ -143,33 +143,33 @@ public final class NBTUtils { */ public static Class getTypeClass(int type) { switch (type) { - case NBTConstants.TYPE_END: - return EndTag.class; - case NBTConstants.TYPE_BYTE: - return ByteTag.class; - case NBTConstants.TYPE_SHORT: - return ShortTag.class; - case NBTConstants.TYPE_INT: - return IntTag.class; - case NBTConstants.TYPE_LONG: - return LongTag.class; - case NBTConstants.TYPE_FLOAT: - return FloatTag.class; - case NBTConstants.TYPE_DOUBLE: - return DoubleTag.class; - case NBTConstants.TYPE_BYTE_ARRAY: - return ByteArrayTag.class; - case NBTConstants.TYPE_STRING: - return StringTag.class; - case NBTConstants.TYPE_LIST: - return ListTag.class; - case NBTConstants.TYPE_COMPOUND: - return CompoundTag.class; - case NBTConstants.TYPE_INT_ARRAY: - return IntArrayTag.class; - default: - throw new IllegalArgumentException("Invalid tag type : " + type - + "."); + case NBTConstants.TYPE_END: + return EndTag.class; + case NBTConstants.TYPE_BYTE: + return ByteTag.class; + case NBTConstants.TYPE_SHORT: + return ShortTag.class; + case NBTConstants.TYPE_INT: + return IntTag.class; + case NBTConstants.TYPE_LONG: + return LongTag.class; + case NBTConstants.TYPE_FLOAT: + return FloatTag.class; + case NBTConstants.TYPE_DOUBLE: + return DoubleTag.class; + case NBTConstants.TYPE_BYTE_ARRAY: + return ByteArrayTag.class; + case NBTConstants.TYPE_STRING: + return StringTag.class; + case NBTConstants.TYPE_LIST: + return ListTag.class; + case NBTConstants.TYPE_COMPOUND: + return CompoundTag.class; + case NBTConstants.TYPE_INT_ARRAY: + return IntArrayTag.class; + default: + throw new IllegalArgumentException("Invalid tag type : " + type + + "."); } } @@ -192,37 +192,37 @@ public final class NBTUtils { } return expected.cast(tag); } - - + + public static byte[] toBytesCompressed(String name, CompoundTag tag) { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - try (NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(byteStream))) - { - nbtStream.writeNamedTag(name, tag); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } - return byteStream.toByteArray(); + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + try (NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(byteStream))) + { + nbtStream.writeNamedTag(name, tag); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + return byteStream.toByteArray(); } - + public static NamedTag getFromBytesCompressed(byte[] bytes) { - try (NBTInputStream stream = new NBTInputStream(new GZIPInputStream(new ByteArrayInputStream(bytes)));) - { - return stream.readNamedTag(); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } + try (NBTInputStream stream = new NBTInputStream(new GZIPInputStream(new ByteArrayInputStream(bytes)));) + { + return stream.readNamedTag(); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } } - - + + public static NBTBase toNative(Tag tag) { if (tag instanceof IntArrayTag) { return toNative((IntArrayTag) tag); @@ -422,20 +422,20 @@ public final class NBTUtils { public static DoubleTag fromNative(NBTTagDouble other) { return new DoubleTag(other.g()); } - + public static NBTTagList doubleArrayToList(double... doubles) { - NBTTagList nbttaglist = new NBTTagList(); - for(double d : doubles) - { - nbttaglist.add(new NBTTagDouble(d)); - } - return nbttaglist; + NBTTagList nbttaglist = new NBTTagList(); + for(double d : doubles) + { + nbttaglist.add(new NBTTagDouble(d)); + } + return nbttaglist; } - + public static Vector getVector(CompoundTag tag) { - return new Vector(tag.asDouble("x"), tag.asDouble("y"), tag.asDouble("z")); + return new Vector(tag.asDouble("x"), tag.asDouble("y"), tag.asDouble("z")); } } diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/Constants.java b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/Constants.java index 4cb216fb..32a6014c 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/Constants.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/Constants.java @@ -1,16 +1,26 @@ package mineplex.core.common; -import com.google.gson.*; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.UUID; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.PropertyMap; import com.mojang.util.UUIDTypeAdapter; -import java.lang.reflect.Type; -import java.util.UUID; - public class Constants { - public static final String WEB_ADDRESS = "http://127.0.0.1:1000/"; + public static final String WEB_ADDRESS = "http://accounts.mineplex.com/"; public static final String WEB_CONFIG_KEY = "webServer"; public static Gson GSON; diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java index 351af146..b1593c55 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/api/ApiHost.java @@ -1,8 +1,11 @@ package mineplex.core.common.api; +import java.io.File; import java.util.HashMap; import java.util.Map; +import org.bukkit.configuration.file.YamlConfiguration; + public class ApiHost { private static final String API_HOST_FILE = "api-config.dat"; @@ -22,7 +25,6 @@ public class ApiHost { try { - /* File configFile = new File(API_HOST_FILE); YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); @@ -38,13 +40,6 @@ public class ApiHost API_HOST_MAP.put(key, new ApiHost(ip, port)); } - Manually putting datas - */ - API_HOST_MAP.put("AMPLIFIERS", new ApiHost("127.0.0.1", 1000)); - API_HOST_MAP.put("ANTISPAM", new ApiHost("127.0.0.1", 1000)); - API_HOST_MAP.put("ENDERCHEST", new ApiHost("127.0.0.1", 1000)); - API_HOST_MAP.put("BANNER", new ApiHost("127.0.0.1", 1000)); - } catch (Throwable t) { diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/block/MultiBlockUpdaterAgent.java b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/block/MultiBlockUpdaterAgent.java index 1e8680ef..c5b812ac 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/block/MultiBlockUpdaterAgent.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/block/MultiBlockUpdaterAgent.java @@ -105,7 +105,9 @@ public class MultiBlockUpdaterAgent { for(Player p : players) { - int protocol = UtilPlayer.getProtocol(p); + //TODO: Multi-protocol support + //int protocol = UtilPlayer.getProtocol(p); + //UtilPlayer.sendPacket(p, new PacketPlayOutMapChunk(protocol, c, true, 65535)); UtilPlayer.sendPacket(p, new PacketPlayOutMapChunk(c, true, 65535)); } } diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/SpigotUtil.java b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/SpigotUtil.java index 52c79a9f..0450a5d2 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/SpigotUtil.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/SpigotUtil.java @@ -1,8 +1,8 @@ package mineplex.core.common.util; +import net.minecraft.server.v1_8_R3.EntityTameableAnimal; import com.google.common.base.Optional; -import net.minecraft.server.v1_8_R3.EntityTameableAnimal; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftTameableAnimal; import org.bukkit.entity.AnimalTamer; import org.bukkit.entity.Tameable; diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java index 1b8c4791..8790d659 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java @@ -1073,6 +1073,11 @@ public class UtilEnt public static void registerEntityType(Class customClass, EntityType entityType, String name) { + //TODO: Balloon | Custom entity(?) + //For now: we have no way of registering these, well.. as i know, im not a spigot dev + //EntityTypes.getNameToClassMap().remove(name); + //EntityTypes.getIdToClassMap().remove((int) entityType.getTypeId()); + //EntityTypes.register(customClass, name, (int) entityType.getTypeId()); } public static void spawnEntity(net.minecraft.server.v1_8_R3.Entity entity, Location location) diff --git a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java index 68f164b6..e23ca509 100644 --- a/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java +++ b/Plugins[Modified]/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java @@ -26,7 +26,6 @@ import net.minecraft.server.v1_8_R3.EntityPlayer; import net.minecraft.server.v1_8_R3.EntityTracker; import net.minecraft.server.v1_8_R3.EntityTrackerEntry; import net.minecraft.server.v1_8_R3.Packet; - import net.minecraft.server.v1_8_R3.PacketPlayOutNamedSoundEffect; import net.minecraft.server.v1_8_R3.PacketPlayOutWorldBorder; import net.minecraft.server.v1_8_R3.PlayerConnection; @@ -51,6 +50,10 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.BlockIterator; import org.bukkit.util.Vector; +//TODO: Multi-protocol support +//import com.mineplex.ProtocolVersion; +//import net.minecraft.server.v1_8_R3.PacketPlayOutCustomSoundEffect; + import mineplex.core.common.MinecraftVersion; public class UtilPlayer @@ -1168,6 +1171,18 @@ public class UtilPlayer int protocol = getProtocol(player); Location location = player.getLocation(); packet = new PacketPlayOutNamedSoundEffect(sound.getAudioPath(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), 20, 1); + //TODO: Multi-protocol support + /* + if (protocol >= ProtocolVersion.v1_12) + { + packet = new PacketPlayOutCustomSoundEffect(sound.getAudioPath(), location.getX(), location.getY(), location.getZ(), 20, 1); + } + else + { + packet = new PacketPlayOutNamedSoundEffect(sound.getAudioPath(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), 20, 1); + } + */ + sendPacket(player, packet); } @@ -1200,6 +1215,7 @@ public class UtilPlayer public static int getProtocol(Player player) { + //return ((CraftPlayer) player).getHandle().getProtocol(); return ((CraftPlayer) player).getHandle().playerConnection.networkManager.getVersion(); } diff --git a/Plugins[Modified]/Mineplex.Core/pom.xml b/Plugins[Modified]/Mineplex.Core/pom.xml index 9c0ae521..e716914c 100644 --- a/Plugins[Modified]/Mineplex.Core/pom.xml +++ b/Plugins[Modified]/Mineplex.Core/pom.xml @@ -59,17 +59,11 @@ junit test - - com.labalityowo - spigot - compile - - noop version.properties diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/TwitchIntegrationFix.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/TwitchIntegrationFix.java new file mode 100644 index 00000000..ce8bb842 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/TwitchIntegrationFix.java @@ -0,0 +1,128 @@ +package mineplex.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.PacketPlayInArmAnimation; +import net.minecraft.server.v1_8_R3.PacketPlayInBlockDig; +import net.minecraft.server.v1_8_R3.PacketPlayInBlockPlace; +import net.minecraft.server.v1_8_R3.PacketPlayInEntityAction; +import net.minecraft.server.v1_8_R3.PacketPlayInFlying; +import net.minecraft.server.v1_8_R3.PacketPlayInHeldItemSlot; +import net.minecraft.server.v1_8_R3.PacketPlayInRightClick; +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutCloseWindow; +import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow; + +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketInfo; + +/** + * Why do we need this you ask? + *

+ * In 1.8.x, Mojang added Twitch integration, and in standard Mojang fashion completely broke inventory handling. + *

+ * Specifically, you are able to close an inventory and not actually trigger an InventoryCloseEvent. This kinda breaks + * literally anything relying on that event. + *

+ * So we just add lots of strict checks to make sure they can't do much without closing the inventory + */ +@ReflectivelyCreateMiniPlugin +public class TwitchIntegrationFix extends MiniPlugin implements IPacketHandler +{ + private final Map _inventoryOpenedAt = new HashMap<>(); + private final Map _inventoryOpenedAtTime = new HashMap<>(); + + private TwitchIntegrationFix() + { + super("Twitch Integration Fix"); + + require(PacketHandler.class).addPacketHandler(this, true, + PacketPlayOutOpenWindow.class, + PacketPlayOutCloseWindow.class, + PacketPlayInRightClick.class, + PacketPlayInBlockPlace.class, + PacketPlayInArmAnimation.class, + PacketPlayInBlockDig.class, + PacketPlayInHeldItemSlot.class, + PacketPlayInUseEntity.class, + PacketPlayInFlying.PacketPlayInPosition.class, + PacketPlayInFlying.PacketPlayInPositionLook.class + ); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + _inventoryOpenedAt.remove(event.getPlayer().getUniqueId()); + _inventoryOpenedAtTime.remove(event.getPlayer().getUniqueId()); + } + + @Override + public void handle(PacketInfo packetInfo) + { + EntityPlayer entityPlayer = ((CraftPlayer) packetInfo.getPlayer()).getHandle(); + //TODO: No idea what this is tbh, im just commenting out if someone can figure this out + /* + if (packetInfo.getPacket() instanceof PacketPlayOutOpenWindow) + { + _inventoryOpenedAt.put(packetInfo.getPlayer().getUniqueId(), packetInfo.getPlayer().getLocation()); + _inventoryOpenedAtTime.put(packetInfo.getPlayer().getUniqueId(), entityPlayer.playerConnection.networkManager.packetCount); + } + else if (packetInfo.getPacket() instanceof PacketPlayOutCloseWindow) + { + _inventoryOpenedAt.remove(packetInfo.getPlayer().getUniqueId()); + _inventoryOpenedAtTime.remove(packetInfo.getPlayer().getUniqueId()); + } + else if (packetInfo.getPacket() instanceof PacketPlayInRightClick || + packetInfo.getPacket() instanceof PacketPlayInBlockPlace || + packetInfo.getPacket() instanceof PacketPlayInArmAnimation || + packetInfo.getPacket() instanceof PacketPlayInBlockDig || + packetInfo.getPacket() instanceof PacketPlayInHeldItemSlot || + packetInfo.getPacket() instanceof PacketPlayInUseEntity + ) + { + // Impossible to do while inventory is open + if (entityPlayer.activeContainer != entityPlayer.defaultContainer && _inventoryOpenedAtTime.containsKey(packetInfo.getPlayer().getUniqueId())) + { + long openedTime = _inventoryOpenedAtTime.get(packetInfo.getPlayer().getUniqueId()); + if (entityPlayer.playerConnection.networkManager.packetCount - openedTime > 5) + { + System.out.println("Impossible packet: " + packetInfo.getPacket().getClass()); + packetInfo.getPlayer().closeInventory(); + } + } + } + else*/ if (packetInfo.getPacket() instanceof PacketPlayInFlying) + { + if (entityPlayer.activeContainer != entityPlayer.defaultContainer) + { + if (_inventoryOpenedAt.containsKey(packetInfo.getPlayer().getUniqueId())) + { + Location openedAt = _inventoryOpenedAt.get(packetInfo.getPlayer().getUniqueId()); + if (!packetInfo.getPlayer().getWorld().equals(openedAt.getWorld())) + { + packetInfo.getPlayer().closeInventory(); + } + else + { + double distance = packetInfo.getPlayer().getLocation().distanceSquared(openedAt); + // You get a 9 block radius before you're considered too far away + if (distance > 9 * 9) + { + packetInfo.getPlayer().closeInventory(); + } + } + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java index ff89aeb3..0bc28800 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java @@ -1,30 +1,24 @@ package mineplex.core.account; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import mineplex.cache.player.PlayerCache; -import mineplex.cache.player.PlayerInfo; -import mineplex.core.MiniPlugin; -import mineplex.core.account.command.RanksCommand; -import mineplex.core.account.event.ClientUnloadEvent; -import mineplex.core.account.event.ClientWebResponseEvent; -import mineplex.core.account.event.OnlinePrimaryGroupUpdateEvent; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.account.permissions.PermissionGroupHelper; -import mineplex.core.account.redis.*; -import mineplex.core.account.repository.AccountRepository; -import mineplex.core.account.repository.token.ClientToken; -import mineplex.core.common.Pair; -import mineplex.core.common.timing.TimingManager; -import mineplex.core.common.util.*; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.core.utils.UtilGameProfile; -import mineplex.core.utils.UtilScheduler; -import mineplex.serverdata.commands.ServerCommandManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.regex.Pattern; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -36,17 +30,43 @@ import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.java.JavaPlugin; -import java.sql.SQLException; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.regex.Pattern; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.Sets; +import com.google.gson.Gson; + +import mineplex.cache.player.PlayerCache; +import mineplex.cache.player.PlayerInfo; +import mineplex.core.MiniPlugin; +import mineplex.core.account.command.RanksCommand; +import mineplex.core.account.event.ClientUnloadEvent; +import mineplex.core.account.event.ClientWebResponseEvent; +import mineplex.core.account.event.OnlinePrimaryGroupUpdateEvent; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.account.permissions.PermissionGroupHelper; +import mineplex.core.account.redis.AddPermissionGroup; +import mineplex.core.account.redis.AddPermissionGroupHandler; +import mineplex.core.account.redis.ClearGroups; +import mineplex.core.account.redis.ClearGroupsHandler; +import mineplex.core.account.redis.PrimaryGroupUpdate; +import mineplex.core.account.redis.PrimaryGroupUpdateHandler; +import mineplex.core.account.redis.RemovePermissionGroup; +import mineplex.core.account.redis.RemovePermissionGroupHandler; +import mineplex.core.account.repository.AccountRepository; +import mineplex.core.account.repository.token.ClientToken; +import mineplex.core.common.Pair; +import mineplex.core.common.timing.TimingManager; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTasks; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.utils.UtilGameProfile; +import mineplex.core.utils.UtilScheduler; +import mineplex.serverdata.commands.ServerCommandManager; public class CoreClientManager extends MiniPlugin { @@ -307,9 +327,9 @@ public class CoreClientManager extends MiniPlugin client.setAccountId(result.getLeft()); if (result.getRight().getLeft() == null) { - //PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(token.Rank); - client.setPrimaryGroup(PermissionGroup.PLAYER); - _repository.setPrimaryGroup(client.getAccountId(), PermissionGroup.PLAYER, null); + PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(token.Rank); + client.setPrimaryGroup(newGroup); + _repository.setPrimaryGroup(client.getAccountId(), newGroup, null); } else { @@ -387,9 +407,9 @@ public class CoreClientManager extends MiniPlugin client.setAccountId(result.getLeft()); if (result.getRight().getLeft() == null) { - //PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(token.Rank); - client.setPrimaryGroup(PermissionGroup.PLAYER); - _repository.setPrimaryGroup(client.getAccountId(), PermissionGroup.PLAYER, null); + PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(token.Rank); + client.setPrimaryGroup(newGroup); + _repository.setPrimaryGroup(client.getAccountId(), newGroup, null); } else { @@ -465,12 +485,11 @@ public class CoreClientManager extends MiniPlugin Pair>> result = _repository.login(_loginProcessors, uuid, client.getName()); client.setAccountId(result.getLeft()); - if (result.getRight().getLeft() == null) { - //PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(token.Rank); - client.setPrimaryGroup(PermissionGroup.PLAYER); - _repository.setPrimaryGroup(client.getAccountId(), PermissionGroup.PLAYER, null); + PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(token.Rank); + client.setPrimaryGroup(newGroup); + _repository.setPrimaryGroup(client.getAccountId(), newGroup, null); } else { @@ -567,12 +586,10 @@ public class CoreClientManager extends MiniPlugin if (client.getRawPrimaryGroup() == null) { - /* String mssqlRank = token.Rank; PermissionGroup newGroup = PermissionGroupHelper.getGroupFromLegacy(mssqlRank); - */ - client.setPrimaryGroup(PermissionGroup.PLAYER); - _repository.setPrimaryGroup(client.getAccountId(), PermissionGroup.PLAYER, null); + client.setPrimaryGroup(newGroup); + _repository.setPrimaryGroup(client.getAccountId(), newGroup, null); } TimingManager.start(client.getName() + " Event."); @@ -586,7 +603,6 @@ public class CoreClientManager extends MiniPlugin { PlayerCache.getInstance().updateAccountId(uuid, client.getAccountId()); } - System.out.println(client.getPrimaryGroup().toString()); return !CLIENT_LOGIN_LOCKS.containsKey(client.getName()); } @@ -873,7 +889,6 @@ public class CoreClientManager extends MiniPlugin public void addStoredProcedureLoginProcessor(ILoginProcessor processor) { - System.out.println("Query of processor " + processor.getName() + " " + processor.getQuery(1, "1", "1") + "\n"); _loginProcessors.add(processor); } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java index 6d47f65d..c414ef34 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java @@ -1,6 +1,26 @@ package mineplex.core.account.repository; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.apache.commons.dbcp2.BasicDataSource; + import com.google.gson.reflect.TypeToken; + import mineplex.cache.player.PlayerCache; import mineplex.core.account.ILoginProcessor; import mineplex.core.account.event.GroupAddEvent; @@ -15,15 +35,6 @@ import mineplex.core.database.MinecraftRepository; import mineplex.serverdata.database.DBPool; import mineplex.serverdata.database.column.ColumnInt; import mineplex.serverdata.database.column.ColumnVarChar; -import org.apache.commons.dbcp2.BasicDataSource; - -import java.sql.*; -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.stream.Collectors; public class AccountRepository extends MinecraftRepository { @@ -119,7 +130,6 @@ public class AccountRepository extends MinecraftRepository // We can use a parallel stream because they will be in the correct order when we collect loginString += loginProcessors.parallelStream().map(processor -> processor.getQuery(finalId, uuidString, name)).collect(Collectors.joining()); - statement.execute(loginString); System.out.println("EXECUTE COMPLETE - " + accountId); @@ -165,6 +175,7 @@ public class AccountRepository extends MinecraftRepository token.Name = name; token.Uuid = uuid.toString(); token.IpAddress = ipAddress; + return handleSyncMSSQLCallStream("PlayerAccount/Login", token); } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index f60f67ab..e3debbc1 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -1,5 +1,24 @@ package mineplex.core.bonuses; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.jooq.DSLContext; +import org.jooq.Record2; +import org.jooq.SQLDialect; +import org.jooq.TableField; +import org.jooq.impl.DSL; + import mineplex.core.common.Pair; import mineplex.core.common.util.Callback; import mineplex.core.common.util.UtilServer; @@ -10,17 +29,6 @@ import mineplex.database.tables.records.BonusRecord; import mineplex.serverdata.database.DBPool; import mineplex.serverdata.database.RepositoryBase; import mineplex.serverdata.database.ResultSetCallable; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.jooq.DSLContext; -import org.jooq.Record2; -import org.jooq.SQLDialect; -import org.jooq.TableField; -import org.jooq.impl.DSL; - -import java.sql.*; public class BonusRepository extends RepositoryBase { diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java index fb385605..1601f7d5 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterManager.java @@ -119,7 +119,7 @@ public class BoosterManager extends MiniPlugin _giveInterfaceItem = canActivateBoosters(); new BoosterUpdateRepository(plugin); - + generatePermissions(); } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java index c8e47374..2f42602e 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/boosters/BoosterRepository.java @@ -1,11 +1,14 @@ package mineplex.core.boosters; import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; +import com.mojang.authlib.properties.PropertyMap; import mineplex.core.common.api.ApiEndpoint; import mineplex.core.common.api.ApiFieldNamingStrategy; import mineplex.core.common.api.ApiHost; +import mineplex.core.common.api.ApiResponse; import java.util.Arrays; import java.util.List; @@ -22,6 +25,7 @@ public class BoosterRepository extends ApiEndpoint public BoosterRepository() { 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()); } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/chat/Chat.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/chat/Chat.java index 5f36eadc..6c6d1fd7 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/chat/Chat.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/chat/Chat.java @@ -1,23 +1,31 @@ package mineplex.core.chat; -import mineplex.core.MiniPlugin; -import mineplex.core.ReflectivelyCreateMiniPlugin; -import mineplex.core.account.CoreClient; -import mineplex.core.account.CoreClientManager; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.chat.command.*; -import mineplex.core.chat.event.FormatPlayerChatEvent; -import mineplex.core.chat.format.ChatFormatComponent; -import mineplex.core.common.util.*; -import mineplex.core.incognito.IncognitoManager; -import mineplex.core.preferences.Preference; -import mineplex.core.preferences.PreferencesManager; -import mineplex.core.preferences.UserPreferences; -import mineplex.core.recharge.Recharge; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.Charset; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.stream.Collectors; + import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; + import org.bukkit.ChatColor; +import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -30,17 +38,29 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; -import javax.net.ssl.*; -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.Charset; -import java.security.cert.X509Certificate; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.chat.command.BroadcastCommand; +import mineplex.core.chat.command.ChatSlowCommand; +import mineplex.core.chat.command.HelpCommand; +import mineplex.core.chat.command.ListEmotesCommand; +import mineplex.core.chat.command.SilenceCommand; +import mineplex.core.chat.event.FormatPlayerChatEvent; +import mineplex.core.chat.format.ChatFormatComponent; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTime; +import mineplex.core.incognito.IncognitoManager; +import mineplex.core.preferences.Preference; +import mineplex.core.preferences.PreferencesManager; +import mineplex.core.preferences.UserPreferences; +import mineplex.core.recharge.Recharge; @ReflectivelyCreateMiniPlugin public class Chat extends MiniPlugin @@ -864,7 +884,7 @@ public class Chat extends MiniPlugin String message = event.getMessage(); message = decapsifyIfNecessary(event.getPlayer(), message); - //message = filterMessage(event.getPlayer(), true, message); + message = filterMessage(event.getPlayer(), true, message); event.setMessage(message); } @@ -884,7 +904,6 @@ public class Chat extends MiniPlugin event.setCancelled(true); return; } - /* runAsync(() -> { @@ -900,8 +919,6 @@ public class Chat extends MiniPlugin sign.update(); }); }); - - */ } @EventHandler diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/command/CommandCenter.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/command/CommandCenter.java index 5c4f1a92..7560f423 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/command/CommandCenter.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/command/CommandCenter.java @@ -1,20 +1,22 @@ package mineplex.core.command; -import com.google.common.collect.Lists; -import mineplex.core.Managers; -import mineplex.core.account.CoreClient; -import mineplex.core.account.CoreClientManager; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.common.util.*; -import mineplex.core.packethandler.IPacketHandler; -import mineplex.core.packethandler.PacketHandler; -import mineplex.core.packethandler.PacketInfo; -import mineplex.core.recharge.Recharge; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + import net.minecraft.server.v1_8_R3.EntityPlayer; import net.minecraft.server.v1_8_R3.PacketPlayInTabComplete; +//import net.minecraft.server.v1_8_R3.PacketPlayOutDeclareCommands; import net.minecraft.server.v1_8_R3.PacketPlayOutTabComplete; import net.minecraft.server.v1_8_R3.PlayerConnection; + import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -23,9 +25,24 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; -import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import com.google.common.collect.Lists; +//import com.mineplex.ProtocolVersion; + +import mineplex.core.Managers; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilPlayerBase; +import mineplex.core.common.util.UtilServer; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketInfo; +import mineplex.core.recharge.Recharge; public class CommandCenter implements Listener, IPacketHandler { @@ -200,9 +217,8 @@ public class CommandCenter implements Listener, IPacketHandler @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - int protocol = UtilPlayer.getProtocol(event.getPlayer()); /* - TODO: Protocol Support + int protocol = UtilPlayer.getProtocol(event.getPlayer()); if (protocol >= ProtocolVersion.v1_13) { List commands = getCommands(event.getPlayer()); @@ -217,14 +233,12 @@ public class CommandCenter implements Listener, IPacketHandler if (packetInfo.getPacket() instanceof PacketPlayInTabComplete) { EntityPlayer nmsPlayer = ((CraftPlayer) packetInfo.getPlayer()).getHandle(); + //TODO: Multi-protocol support /* - - TODO: ProtocolSupport if (nmsPlayer.getProtocol() >= ProtocolVersion.v1_13) { return; } - */ PacketPlayInTabComplete packet = (PacketPlayInTabComplete) packetInfo.getPacket(); diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java index ab334915..8b3e25b2 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java @@ -186,8 +186,8 @@ public class CosmeticManager extends MiniPlugin public void setInterfaceSlot(int i) { - System.out.println(_gadgetManager.toString()); _interfaceSlot = i; + _gadgetManager.setActiveItemSlot(i-1); } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java index 3280e24d..c4dda8e7 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java @@ -1,21 +1,45 @@ package mineplex.core.disguise; -import com.mineplex.spigot.ChunkAddEntityEvent; -import mineplex.core.MiniPlugin; -import mineplex.core.PlayerSelector; -import mineplex.core.ReflectivelyCreateMiniPlugin; -import mineplex.core.common.util.*; -import mineplex.core.disguise.disguises.*; -import mineplex.core.packethandler.IPacketHandler; -import mineplex.core.packethandler.PacketHandler; -import mineplex.core.packethandler.PacketInfo; -import mineplex.core.packethandler.PacketVerifier; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import net.minecraft.server.v1_8_R3.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; + +import net.minecraft.server.v1_8_R3.BlockBed; +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.EntityPlayer; +import net.minecraft.server.v1_8_R3.EntityTrackerEntry; +import net.minecraft.server.v1_8_R3.EnumDirection; +import net.minecraft.server.v1_8_R3.MinecraftServer; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayOutBed; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntity; import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutEntityLook; import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMove; import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityVelocity; +import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk; +import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn; +import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; +import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateAttributes; +//import net.minecraft.server.v1_8_R3.PacketPlayOutVehicleMove; +import net.minecraft.server.v1_8_R3.WorldServer; +import net.minecraft.server.v1_8_R3.WorldSettings; + import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.block.BlockFace; @@ -34,8 +58,29 @@ import org.bukkit.scoreboard.NameTagVisibility; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; -import java.util.*; -import java.util.function.Predicate; +import com.mineplex.spigot.ChunkAddEntityEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.PlayerSelector; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilLambda; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTasks; +import mineplex.core.disguise.disguises.DisguiseBase; +import mineplex.core.disguise.disguises.DisguiseBlock; +import mineplex.core.disguise.disguises.DisguiseInsentient; +import mineplex.core.disguise.disguises.DisguiseLiving; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.disguise.disguises.DisguiseSquid; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketInfo; +import mineplex.core.packethandler.PacketVerifier; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; /* * notes: rabbit jump has been removed (PacketPlayOutEntityStatus) because it didn't work for 1.9+ anyways @@ -352,6 +397,7 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler final Packet packet = packetInfo.getPacket(); final Player owner = packetInfo.getPlayer(); final PacketVerifier packetVerifier = packetInfo.getVerifier(); + //final int protocol = ((CraftPlayer) owner).getHandle().getProtocol(); final int protocol = ((CraftPlayer) owner).getHandle().playerConnection.networkManager.getVersion(); if (packet instanceof PacketPlayOutPlayerInfo) @@ -653,6 +699,7 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler if (disguise.getEntity() == nmsPlayer) continue; + //int protocol = nmsPlayer.getProtocol(); int protocol = nmsPlayer.playerConnection.networkManager.getVersion(); UtilPlayer.sendPacket(player, disguise.modifyMetaPacket(protocol, disguise.getMetadataPacket())); } @@ -777,9 +824,14 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler List packets = new ArrayList<>(); EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle(); + //int protocol = nmsPlayer.getProtocol(); int protocol = nmsPlayer.playerConnection.networkManager.getVersion(); - PacketPlayOutMapChunk chunk = new PacketPlayOutMapChunk(_bedChunk, true, '\uffff'); + //TODO: Multi-protocol support + /* + PacketPlayOutMapChunk chunk = new PacketPlayOutMapChunk(protocol, _bedChunk, true, '\uffff'); + + */ chunk.a = BED_POS_NORTH[0] >> 4; chunk.b = BED_POS_NORTH[2] >> 4; @@ -830,6 +882,8 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler double d2 = posZ + (targetZ - posZ) / (double) partitions; + //TODO: Protocol support + //PacketPlayOutMapChunk chunk = new PacketPlayOutMapChunk(protocol, _bedChunk, true, '\uffff'); PacketPlayOutMapChunk chunk = new PacketPlayOutMapChunk(_bedChunk, true, '\uffff'); chunk.a = (int) Math.floor(d0) >> 4; chunk.b = (int) Math.floor(d2) >> 4; diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseBase.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseBase.java index 51bc2422..fd9caa88 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseBase.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseBase.java @@ -1,13 +1,5 @@ package mineplex.core.disguise.disguises; -import mineplex.core.common.DummyEntity; -import mineplex.core.common.util.UtilPlayer; -import net.minecraft.server.v1_8_R3.*; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent; - import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; @@ -15,6 +7,16 @@ import java.util.List; import java.util.function.Predicate; import java.util.function.Supplier; +import net.minecraft.server.v1_8_R3.*; + +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.CreatureSpawnEvent; + +import mineplex.core.common.DummyEntity; +import mineplex.core.common.util.UtilPlayer; + public abstract class DisguiseBase { private WeakReference _entity = new WeakReference<>(null); @@ -87,6 +89,7 @@ public abstract class DisguiseBase for (EntityPlayer player : tracker.get(getEntity().getId()).trackedPlayers) { + //int protocol = player.getProtocol(); int protocol = player.playerConnection.networkManager.getVersion(); if (!protocolPredicate.test(protocol)) continue; diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseCreature.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseCreature.java index 988f0def..03f22084 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseCreature.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseCreature.java @@ -1,8 +1,15 @@ package mineplex.core.disguise.disguises; -import net.minecraft.server.v1_8_R3.MathHelper; -import net.minecraft.server.v1_8_R3.Packet; -import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +//import com.mineplex.MetadataRewriter; +//import com.mineplex.ProtocolVersion; + +import net.minecraft.server.v1_8_R3.*; +import net.minecraft.server.v1_8_R3.DataWatcher.WatchableObject; + import org.bukkit.entity.EntityType; public abstract class DisguiseCreature extends DisguiseInsentient @@ -78,8 +85,8 @@ public abstract class DisguiseCreature extends DisguiseInsentient @Override public Packet modifySpawnPacket(int protocol, Packet packet) { + //TODO: Multi-protocol support /* - TODO: Protocol Support/Prob Never since i dont have their MetadataWriter if (protocol >= ProtocolVersion.v1_10_PRE) { PacketPlayOutSpawnEntityLiving newSpawn = (PacketPlayOutSpawnEntityLiving) getSpawnPacket(); @@ -126,8 +133,7 @@ public abstract class DisguiseCreature extends DisguiseInsentient newSpawn.m = meta; return newSpawn; } - - */ + */ return packet; } @@ -142,9 +148,8 @@ public abstract class DisguiseCreature extends DisguiseInsentient @Override public Packet modifyMetaPacket(int protocol, Packet packet) { + //TODO: Multi-protocol support /* - - TODO: Again Protocol Support/Prob never since i dont have their metadatawriter if (protocol >= ProtocolVersion.v1_10_PRE) { PacketPlayOutEntityMetadata newMeta = new PacketPlayOutEntityMetadata(); @@ -168,7 +173,7 @@ public abstract class DisguiseCreature extends DisguiseInsentient return newMeta; } - */ + */ return packet; } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseEnderman.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseEnderman.java index a9257efe..92c36730 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseEnderman.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseEnderman.java @@ -1,11 +1,19 @@ package mineplex.core.disguise.disguises; -import com.google.common.base.Optional; -import net.minecraft.server.v1_8_R3.*; -import org.bukkit.entity.EntityType; - import java.util.Arrays; +import net.minecraft.server.v1_8_R3.Block; +import net.minecraft.server.v1_8_R3.Blocks; +import net.minecraft.server.v1_8_R3.EntityEnderman; +import net.minecraft.server.v1_8_R3.EntityLiving; +import net.minecraft.server.v1_8_R3.IBlockData; +import net.minecraft.server.v1_8_R3.MobEffect; +import net.minecraft.server.v1_8_R3.MobEffectList; +import net.minecraft.server.v1_8_R3.PotionBrewer; + +import com.google.common.base.Optional; +import org.bukkit.entity.EntityType; + public class DisguiseEnderman extends DisguiseMonster { public DisguiseEnderman(org.bukkit.entity.Entity entity) diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseMutable.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseMutable.java index 7315be01..35f46b41 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseMutable.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseMutable.java @@ -1,7 +1,12 @@ package mineplex.core.disguise.disguises; +import java.util.function.Predicate; + +//import com.mineplex.ProtocolVersion; + import net.minecraft.server.v1_8_R3.Packet; import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; + import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -19,13 +24,14 @@ public abstract class DisguiseMutable extends DisguiseCreature { // if (!_spawnedIn) // return; + //TODO: Multi-protocol support + //Basically sends to players that are > 1.11 but impossible /* Predicate pred = v -> v >= ProtocolVersion.v1_11; sendToWatchers(pred, this::getDestroyPacket); sendToWatchers(pred, this::getSpawnPacket); sendToWatchers(pred, this::getMetadataPacket); - - */ + */ } private Packet getDestroyPacket() diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseTameableAnimal.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseTameableAnimal.java index fedac5f6..7722ed11 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseTameableAnimal.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguiseTameableAnimal.java @@ -1,7 +1,8 @@ package mineplex.core.disguise.disguises; -import com.google.common.base.Optional; import net.minecraft.server.v1_8_R3.EntityTameableAnimal; + +import com.google.common.base.Optional; import org.bukkit.entity.EntityType; public abstract class DisguiseTameableAnimal extends DisguiseAnimal diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java index a894f3e4..834d6cb1 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/donation/repository/DonationRepository.java @@ -1,5 +1,9 @@ package mineplex.core.donation.repository; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + import mineplex.core.common.currency.Currency; import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.util.UtilTasks; @@ -10,10 +14,6 @@ import mineplex.core.donation.repository.token.UnknownPurchaseToken; import mineplex.core.server.util.TransactionResponse; import mineplex.serverdata.database.DBPool; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; - public class DonationRepository extends MinecraftRepository { private static Map WEB_ADDRESSES = new HashMap<>(); @@ -67,7 +67,6 @@ public class DonationRepository extends MinecraftRepository token.AccountName = playerName; token.SalesPackageName = packageName; token.CoinPurchase = currencyType == GlobalCurrency.TREASURE_SHARD; - System.out.println(token.CoinPurchase); token.Cost = cost; token.Premium = false; diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index 657c5299..4ee684cd 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -1,5 +1,36 @@ package mineplex.core.gadget; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.inventory.AnvilInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + import mineplex.core.MiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.account.CoreClientManager; @@ -9,17 +40,89 @@ import mineplex.core.achievement.AchievementManager; import mineplex.core.arcadeevents.CoreGameStartEvent; import mineplex.core.arcadeevents.CoreGameStopEvent; import mineplex.core.blockrestore.BlockRestore; -import mineplex.core.common.util.*; +import mineplex.core.common.skin.SkinData; +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.cosmetic.ui.page.GadgetPage; +import mineplex.core.cosmetic.ui.page.gamemodifiers.GameCosmeticCategoryPage; +import mineplex.core.cosmetic.ui.page.gamemodifiers.moba.HeroSkinCategoryPage; import mineplex.core.disguise.DisguiseManager; import mineplex.core.donation.DonationManager; -import mineplex.core.gadget.commands.*; -import mineplex.core.gadget.event.*; +import mineplex.core.gadget.commands.AmmoCommand; +import mineplex.core.gadget.commands.LockCosmeticsCommand; +import mineplex.core.gadget.commands.TestTauntCommand; +import mineplex.core.gadget.commands.UnlockCosmeticCommand; +import mineplex.core.gadget.commands.UnlockCosmeticsCommand; +import mineplex.core.gadget.event.GadgetBlockEvent; +import mineplex.core.gadget.event.GadgetChangeEvent; import mineplex.core.gadget.event.GadgetChangeEvent.GadgetState; -import mineplex.core.gadget.gadgets.arrowtrail.*; +import mineplex.core.gadget.event.GadgetCollideEntityEvent; +import mineplex.core.gadget.event.GadgetEnableEvent; +import mineplex.core.gadget.event.GadgetSelectLocationEvent; +import mineplex.core.gadget.event.PlayerToggleSwimEvent; +import mineplex.core.gadget.event.TauntCommandEvent; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailBalance; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailBlood; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailCandyCane; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailConfetti; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailCupid; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailEmerald; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailEnchant; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailFreedom; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailFrostLord; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailHalloween; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailLegend; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailMusic; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailPresent; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailRainbow; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailRedWhite; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailShadow; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailSpring; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailStorm; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailTitan; import mineplex.core.gadget.gadgets.balloons.BalloonType; import mineplex.core.gadget.gadgets.chat.LevelPrefixType; -import mineplex.core.gadget.gadgets.death.*; -import mineplex.core.gadget.gadgets.doublejump.*; +import mineplex.core.gadget.gadgets.death.DeathBalance; +import mineplex.core.gadget.gadgets.death.DeathBlood; +import mineplex.core.gadget.gadgets.death.DeathCandyCane; +import mineplex.core.gadget.gadgets.death.DeathCupidsBrokenHeart; +import mineplex.core.gadget.gadgets.death.DeathEmerald; +import mineplex.core.gadget.gadgets.death.DeathEnchant; +import mineplex.core.gadget.gadgets.death.DeathFreedom; +import mineplex.core.gadget.gadgets.death.DeathFrostLord; +import mineplex.core.gadget.gadgets.death.DeathHalloween; +import mineplex.core.gadget.gadgets.death.DeathLegend; +import mineplex.core.gadget.gadgets.death.DeathMapleLeaf; +import mineplex.core.gadget.gadgets.death.DeathMusic; +import mineplex.core.gadget.gadgets.death.DeathPinataBurst; +import mineplex.core.gadget.gadgets.death.DeathPresentDanger; +import mineplex.core.gadget.gadgets.death.DeathRainbow; +import mineplex.core.gadget.gadgets.death.DeathShadow; +import mineplex.core.gadget.gadgets.death.DeathSpring; +import mineplex.core.gadget.gadgets.death.DeathStorm; +import mineplex.core.gadget.gadgets.death.DeathTitan; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpBalance; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpBlood; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpCandyCane; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpCupidsWings; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpEmerald; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpEnchant; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpFirecracker; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpFreedom; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpFrostLord; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpHalloween; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpLegend; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpMaple; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpMusic; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpPresent; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpRainbow; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpShadow; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpSpring; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpStorm; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpTitan; import mineplex.core.gadget.gadgets.flag.FlagType; import mineplex.core.gadget.gadgets.gamemodifiers.GameCosmeticCategory; import mineplex.core.gadget.gadgets.gamemodifiers.GameCosmeticManager; @@ -28,14 +131,107 @@ import mineplex.core.gadget.gadgets.gamemodifiers.minestrike.GameModifierMineStr import mineplex.core.gadget.gadgets.gamemodifiers.minestrike.MineStrikeSkin; import mineplex.core.gadget.gadgets.gamemodifiers.moba.shopmorph.ShopMorphGadget; import mineplex.core.gadget.gadgets.gamemodifiers.moba.shopmorph.ShopMorphType; +import mineplex.core.gadget.gadgets.gamemodifiers.moba.skins.HeroSkinGadget; import mineplex.core.gadget.gadgets.hat.HatItem; import mineplex.core.gadget.gadgets.hat.HatType; -import mineplex.core.gadget.gadgets.item.*; -import mineplex.core.gadget.gadgets.kitselector.*; -import mineplex.core.gadget.gadgets.morph.*; +import mineplex.core.gadget.gadgets.item.ItemBallCatch; +import mineplex.core.gadget.gadgets.item.ItemBatGun; +import mineplex.core.gadget.gadgets.item.ItemBow; +import mineplex.core.gadget.gadgets.item.ItemCandy; +import mineplex.core.gadget.gadgets.item.ItemClacker; +import mineplex.core.gadget.gadgets.item.ItemCoal; +import mineplex.core.gadget.gadgets.item.ItemCoinBomb; +import mineplex.core.gadget.gadgets.item.ItemConnect4; +import mineplex.core.gadget.gadgets.item.ItemGrapplingHook; +import mineplex.core.gadget.gadgets.item.ItemDuelingSword; +import mineplex.core.gadget.gadgets.item.ItemEtherealPearl; +import mineplex.core.gadget.gadgets.item.ItemFirework; +import mineplex.core.gadget.gadgets.item.ItemFleshHook; +import mineplex.core.gadget.gadgets.item.ItemFlowerGift; +import mineplex.core.gadget.gadgets.item.ItemFreezeCannon; +import mineplex.core.gadget.gadgets.item.ItemLovePotion; +import mineplex.core.gadget.gadgets.item.ItemMaryPoppins; +import mineplex.core.gadget.gadgets.item.ItemMelonLauncher; +import mineplex.core.gadget.gadgets.item.ItemMobBomb; +import mineplex.core.gadget.gadgets.item.ItemOAndX; +import mineplex.core.gadget.gadgets.item.ItemPaintballGun; +import mineplex.core.gadget.gadgets.item.ItemPaintbrush; +import mineplex.core.gadget.gadgets.item.ItemPartyPopper; +import mineplex.core.gadget.gadgets.item.ItemSnowball; +import mineplex.core.gadget.gadgets.item.ItemSortal; +import mineplex.core.gadget.gadgets.item.ItemTNT; +import mineplex.core.gadget.gadgets.item.ItemTrampoline; +import mineplex.core.gadget.gadgets.kitselector.HalloweenKitSelector; +import mineplex.core.gadget.gadgets.kitselector.HaloKitSelector; +import mineplex.core.gadget.gadgets.kitselector.RainCloudKitSelector; +import mineplex.core.gadget.gadgets.kitselector.RainbowDanceKitSelector; +import mineplex.core.gadget.gadgets.kitselector.ShimmeringRingKitSelector; +import mineplex.core.gadget.gadgets.kitselector.SingleParticleKitSelector; +import mineplex.core.gadget.gadgets.kitselector.WaterWingsKitSelector; +import mineplex.core.gadget.gadgets.morph.MorphAwkwardRabbit; +import mineplex.core.gadget.gadgets.morph.MorphBat; +import mineplex.core.gadget.gadgets.morph.MorphBlaze; +import mineplex.core.gadget.gadgets.morph.MorphBlock; +import mineplex.core.gadget.gadgets.morph.MorphBobRoss; +import mineplex.core.gadget.gadgets.morph.MorphBunny; +import mineplex.core.gadget.gadgets.morph.MorphChicken; +import mineplex.core.gadget.gadgets.morph.MorphChristmasKing; +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.MorphFreedomFighter; +import mineplex.core.gadget.gadgets.morph.MorphFrostGolem; +import mineplex.core.gadget.gadgets.morph.MorphGhast; +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.MorphMelonHead; +import mineplex.core.gadget.gadgets.morph.MorphMetalMan; +import mineplex.core.gadget.gadgets.morph.MorphOcelot; +import mineplex.core.gadget.gadgets.morph.MorphPig; +import mineplex.core.gadget.gadgets.morph.MorphPumpkinKing; +import mineplex.core.gadget.gadgets.morph.MorphSanta; +import mineplex.core.gadget.gadgets.morph.MorphSkeleton; +import mineplex.core.gadget.gadgets.morph.MorphSlime; +import mineplex.core.gadget.gadgets.morph.MorphSnowman; +import mineplex.core.gadget.gadgets.morph.MorphSquid; +import mineplex.core.gadget.gadgets.morph.MorphTitan; +import mineplex.core.gadget.gadgets.morph.MorphTurkey; +import mineplex.core.gadget.gadgets.morph.MorphUncleSam; +import mineplex.core.gadget.gadgets.morph.MorphVillager; +import mineplex.core.gadget.gadgets.morph.MorphWitch; +import mineplex.core.gadget.gadgets.morph.MorphWither; +import mineplex.core.gadget.gadgets.morph.MorphWolf; import mineplex.core.gadget.gadgets.morph.managers.SoulManager; -import mineplex.core.gadget.gadgets.morph.moba.*; -import mineplex.core.gadget.gadgets.mount.types.*; +import mineplex.core.gadget.gadgets.morph.moba.MorphAnath; +import mineplex.core.gadget.gadgets.morph.moba.MorphBardolf; +import mineplex.core.gadget.gadgets.morph.moba.MorphBiff; +import mineplex.core.gadget.gadgets.morph.moba.MorphDana; +import mineplex.core.gadget.gadgets.morph.moba.MorphDevon; +import mineplex.core.gadget.gadgets.morph.moba.MorphHattori; +import mineplex.core.gadget.gadgets.morph.moba.MorphIvy; +import mineplex.core.gadget.gadgets.morph.moba.MorphLarissa; +import mineplex.core.gadget.gadgets.morph.moba.MorphRowena; +import mineplex.core.gadget.gadgets.mount.types.MountBabyReindeer; +import mineplex.core.gadget.gadgets.mount.types.MountCake; +import mineplex.core.gadget.gadgets.mount.types.MountCart; +import mineplex.core.gadget.gadgets.mount.types.MountChicken; +import mineplex.core.gadget.gadgets.mount.types.MountDragon; +import mineplex.core.gadget.gadgets.mount.types.MountFreedomHorse; +import mineplex.core.gadget.gadgets.mount.types.MountFrost; +import mineplex.core.gadget.gadgets.mount.types.MountLoveTrain; +import mineplex.core.gadget.gadgets.mount.types.MountMule; +import mineplex.core.gadget.gadgets.mount.types.MountNightmareSteed; +import mineplex.core.gadget.gadgets.mount.types.MountPumpkin; +import mineplex.core.gadget.gadgets.mount.types.MountSledge; +import mineplex.core.gadget.gadgets.mount.types.MountSlime; +import mineplex.core.gadget.gadgets.mount.types.MountSpider; +import mineplex.core.gadget.gadgets.mount.types.MountStPatricksHorse; +import mineplex.core.gadget.gadgets.mount.types.MountTitan; +import mineplex.core.gadget.gadgets.mount.types.MountUndead; +import mineplex.core.gadget.gadgets.mount.types.MountValentinesSheep; +import mineplex.core.gadget.gadgets.mount.types.MountZombie; import mineplex.core.gadget.gadgets.outfit.OutfitTeam; import mineplex.core.gadget.gadgets.outfit.freezesuit.OutfitFreezeSuitBoots; import mineplex.core.gadget.gadgets.outfit.freezesuit.OutfitFreezeSuitChestplate; @@ -61,21 +257,125 @@ import mineplex.core.gadget.gadgets.outfit.windup.OutfitWindupBoots; import mineplex.core.gadget.gadgets.outfit.windup.OutfitWindupChestplate; import mineplex.core.gadget.gadgets.outfit.windup.OutfitWindupHelmet; import mineplex.core.gadget.gadgets.outfit.windup.OutfitWindupLeggings; -import mineplex.core.gadget.gadgets.particle.*; -import mineplex.core.gadget.gadgets.particle.christmas.*; -import mineplex.core.gadget.gadgets.particle.freedom.*; +import mineplex.core.gadget.gadgets.particle.ParticleBlood; +import mineplex.core.gadget.gadgets.particle.ParticleCandyCane; +import mineplex.core.gadget.gadgets.particle.ParticleCoalFumes; +import mineplex.core.gadget.gadgets.particle.ParticleDeepSeaSwirl; +import mineplex.core.gadget.gadgets.particle.ParticleFiveYear; +import mineplex.core.gadget.gadgets.particle.ParticleInfused; +import mineplex.core.gadget.gadgets.particle.ParticleEmerald; +import mineplex.core.gadget.gadgets.particle.ParticleEnchant; +import mineplex.core.gadget.gadgets.particle.ParticleWitchsCure; +import mineplex.core.gadget.gadgets.particle.ParticleFairy; +import mineplex.core.gadget.gadgets.particle.ParticleFireRings; +import mineplex.core.gadget.gadgets.particle.ParticleFoot; +import mineplex.core.gadget.gadgets.particle.ParticleFrostLord; +import mineplex.core.gadget.gadgets.particle.ParticleHalloween; +import mineplex.core.gadget.gadgets.particle.ParticleHeart; +import mineplex.core.gadget.gadgets.particle.ParticleMacawWings; +import mineplex.core.gadget.gadgets.particle.ParticleChickenWings; +import mineplex.core.gadget.gadgets.particle.ParticleEnderDragonWings; +import mineplex.core.gadget.gadgets.particle.ParticleFoxTail; +import mineplex.core.gadget.gadgets.particle.ParticleJetPack; +import mineplex.core.gadget.gadgets.particle.ParticleCape; +import mineplex.core.gadget.gadgets.particle.ParticleLegendaryHero; +import mineplex.core.gadget.gadgets.particle.ParticleWolfTail; +import mineplex.core.gadget.gadgets.particle.ParticleLegend; +import mineplex.core.gadget.gadgets.particle.ParticleMusic; +import mineplex.core.gadget.gadgets.particle.ParticlePartyTime; +import mineplex.core.gadget.gadgets.particle.ParticleRain; +import mineplex.core.gadget.gadgets.particle.ParticleRainbow; +import mineplex.core.gadget.gadgets.particle.ParticleRainbowTrail; +import mineplex.core.gadget.gadgets.particle.ParticleTitan; +import mineplex.core.gadget.gadgets.particle.ParticleWingsAngel; +import mineplex.core.gadget.gadgets.particle.ParticleWingsBee; +import mineplex.core.gadget.gadgets.particle.ParticleWingsDemons; +import mineplex.core.gadget.gadgets.particle.ParticleWingsInfernal; +import mineplex.core.gadget.gadgets.particle.ParticleWingsLove; +import mineplex.core.gadget.gadgets.particle.ParticleWingsPixie; +import mineplex.core.gadget.gadgets.particle.ParticleYinYang; +import mineplex.core.gadget.gadgets.particle.christmas.ParticleBlizzard; +import mineplex.core.gadget.gadgets.particle.christmas.ParticleChristmasTree; +import mineplex.core.gadget.gadgets.particle.christmas.ParticleFidgetSpinner; +import mineplex.core.gadget.gadgets.particle.christmas.ParticlePumpkinShield; +import mineplex.core.gadget.gadgets.particle.christmas.ParticleWingsChristmas; +import mineplex.core.gadget.gadgets.particle.freedom.ParticleAuraNiceness; +import mineplex.core.gadget.gadgets.particle.freedom.ParticleCanadian; +import mineplex.core.gadget.gadgets.particle.freedom.ParticleFreedom; +import mineplex.core.gadget.gadgets.particle.freedom.ParticleFreedomFireworks; +import mineplex.core.gadget.gadgets.particle.freedom.ParticleStarSpangled; import mineplex.core.gadget.gadgets.particle.king.CastleManager; import mineplex.core.gadget.gadgets.particle.king.ParticleKing; import mineplex.core.gadget.gadgets.particle.spring.ParticleSpringHalo; -import mineplex.core.gadget.gadgets.taunts.*; +import mineplex.core.gadget.gadgets.taunts.BlowAKissTaunt; +import mineplex.core.gadget.gadgets.taunts.ChickenTaunt; +import mineplex.core.gadget.gadgets.taunts.EasyModeTaunt; +import mineplex.core.gadget.gadgets.taunts.EmojiTaunt; +import mineplex.core.gadget.gadgets.taunts.EternalTaunt; +import mineplex.core.gadget.gadgets.taunts.FrostBreathTaunt; +import mineplex.core.gadget.gadgets.taunts.InfernalTaunt; +import mineplex.core.gadget.gadgets.taunts.RainbowTaunt; import mineplex.core.gadget.gadgets.weaponname.WeaponNameType; -import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.*; +import mineplex.core.gadget.gadgets.wineffect.WinEffectBabyChicken; +import mineplex.core.gadget.gadgets.wineffect.WinEffectEarthquake; +import mineplex.core.gadget.gadgets.wineffect.WinEffectFlames; +import mineplex.core.gadget.gadgets.wineffect.WinEffectHalloween; +import mineplex.core.gadget.gadgets.wineffect.WinEffectLavaTrap; +import mineplex.core.gadget.gadgets.wineffect.WinEffectLightningStrike; +import mineplex.core.gadget.gadgets.wineffect.WinEffectLogo; +import mineplex.core.gadget.gadgets.wineffect.WinEffectLoveIsABattlefield; +import mineplex.core.gadget.gadgets.wineffect.WinEffectMrPunchMan; +import mineplex.core.gadget.gadgets.wineffect.WinEffectPartyAnimal; +import mineplex.core.gadget.gadgets.wineffect.WinEffectPodium; +import mineplex.core.gadget.gadgets.wineffect.WinEffectRiseOfTheElderGuardian; +import mineplex.core.gadget.gadgets.wineffect.WinEffectSnowTrails; +import mineplex.core.gadget.gadgets.wineffect.WinEffectTornado; +import mineplex.core.gadget.gadgets.wineffect.WinEffectWinterWarfare; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankEternal; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankHero; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankLegend; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankTitan; +import mineplex.core.gadget.gadgets.wineffect.rankrooms.rankwineffects.WinEffectRankUltra; import mineplex.core.gadget.mission.GadgetUseTracker; import mineplex.core.gadget.persistence.UserGadgetPersistence; -import mineplex.core.gadget.set.*; -import mineplex.core.gadget.set.suits.*; -import mineplex.core.gadget.types.*; +import mineplex.core.gadget.set.SetBalance; +import mineplex.core.gadget.set.SetCanadian; +import mineplex.core.gadget.set.SetCandyCane; +import mineplex.core.gadget.set.SetCupidsLove; +import mineplex.core.gadget.set.SetEmerald; +import mineplex.core.gadget.set.SetFreedom; +import mineplex.core.gadget.set.SetFrostLord; +import mineplex.core.gadget.set.SetHalloween; +import mineplex.core.gadget.set.SetHowlingWinds; +import mineplex.core.gadget.set.SetLegend; +import mineplex.core.gadget.set.SetMusic; +import mineplex.core.gadget.set.SetParty; +import mineplex.core.gadget.set.SetRainbow; +import mineplex.core.gadget.set.SetShadow; +import mineplex.core.gadget.set.SetSpring; +import mineplex.core.gadget.set.SetTitan; +import mineplex.core.gadget.set.SetVampire; +import mineplex.core.gadget.set.SetWisdom; +import mineplex.core.gadget.set.suits.SetFreezeSuit; +import mineplex.core.gadget.set.suits.SetRaveSuit; +import mineplex.core.gadget.set.suits.SetReindeerSuit; +import mineplex.core.gadget.set.suits.SetSpaceSuit; +import mineplex.core.gadget.set.suits.SetStPatricksSuit; +import mineplex.core.gadget.set.suits.SetWindup; +import mineplex.core.gadget.types.BalloonGadget; +import mineplex.core.gadget.types.DoubleJumpEffectGadget; +import mineplex.core.gadget.types.FlagGadget; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetSet; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.gadget.types.HatGadget; +import mineplex.core.gadget.types.ItemGadget; +import mineplex.core.gadget.types.LevelPrefixGadget; +import mineplex.core.gadget.types.MusicGadget; +import mineplex.core.gadget.types.OutfitGadget; import mineplex.core.gadget.types.OutfitGadget.ArmorSlot; +import mineplex.core.gadget.types.TauntGadget; +import mineplex.core.gadget.types.WeaponNameGadget; import mineplex.core.gadget.util.CostConstants; import mineplex.core.game.GameDisplay; import mineplex.core.hologram.HologramManager; @@ -91,24 +391,6 @@ import mineplex.core.preferences.PreferencesManager; import mineplex.core.projectile.ProjectileManager; import mineplex.core.recharge.Recharge; import mineplex.core.stats.event.PlayerStatsLoadedEvent; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.*; -import org.bukkit.inventory.AnvilInventory; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.util.*; @ReflectivelyCreateMiniPlugin public class GadgetManager extends MiniPlugin @@ -536,7 +818,6 @@ public class GadgetManager extends MiniPlugin } //Win Effects - /* addGadget(new WinEffectPodium(this)); addGadget(new WinEffectLogo(this)); addGadget(new WinEffectMrPunchMan(this)); @@ -552,7 +833,6 @@ public class GadgetManager extends MiniPlugin addGadget(new WinEffectTornado(this)); addGadget(new WinEffectEarthquake(this)); addGadget(new WinEffectPartyAnimal(this)); - */ // Rank based win effects addGadget(new WinEffectRankUltra(this)); @@ -705,7 +985,6 @@ public class GadgetManager extends MiniPlugin @Override public void addCategories() { - /* new GameCosmeticCategory(this, "Hero Skins", SkinData.HATTORI.getSkull(), true) { @Override @@ -720,7 +999,6 @@ public class GadgetManager extends MiniPlugin return new HeroSkinCategoryPage(parent.getPlugin(), parent.getShop(), parent.getClientManager(), parent.getDonationManager(), getCategoryName(), parent.getClient().GetPlayer(), parent); } }; - */ new GameCosmeticCategory(this, "Shop Morph", new ItemStack(Material.GOLD_INGOT), false) { @Override diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/imagemap/CustomItemFrames.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/imagemap/CustomItemFrames.java index 688f6e86..a4dc3fb2 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/imagemap/CustomItemFrames.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/imagemap/CustomItemFrames.java @@ -1,19 +1,32 @@ package mineplex.core.imagemap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.DataWatcher; +import net.minecraft.server.v1_8_R3.EntityItemFrame; +import net.minecraft.server.v1_8_R3.ItemStack; +import net.minecraft.server.v1_8_R3.MinecraftServer; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata; + import com.google.common.base.Optional; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftItemFrame; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; + import mineplex.core.MiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.common.util.UtilPlayer; import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.PacketHandler; import mineplex.core.packethandler.PacketInfo; -import net.minecraft.server.v1_8_R3.*; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftItemFrame; -import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; - -import java.util.*; @ReflectivelyCreateMiniPlugin public class CustomItemFrames extends MiniPlugin implements IPacketHandler diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/monitor/VersionsCommand.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/monitor/VersionsCommand.java index 50ceec64..eef2a9b4 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/monitor/VersionsCommand.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/monitor/VersionsCommand.java @@ -1,11 +1,23 @@ package mineplex.core.monitor; -import mineplex.core.command.CommandBase; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; +import java.lang.reflect.Field; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Player; -import java.util.Map; +//import com.mineplex.ProtocolVersion; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; /** * Statistics on versions @@ -20,13 +32,13 @@ public class VersionsCommand extends CommandBase super(plugin, LagMeter.Perm.VERSIONS_COMMAND, "versions", "getver"); } - /* - TODO: Protocol Support he private void ensureVersions() { if (PRETTY_VERSIONS == null) { PRETTY_VERSIONS = new HashMap<>(); + //TODO: Multi-protocol support + /* for (Field field : ProtocolVersion.class.getFields()) { try @@ -38,24 +50,22 @@ public class VersionsCommand extends CommandBase PRETTY_VERSIONS.put(protocol, version); } catch (ReflectiveOperationException ex) { } } + */ } } - */ - @Override public void Execute(Player caller, String[] args) { - /* - TODO: Protocol Support - //ensureVersions(); + ensureVersions(); if (args.length == 0) { Map versions = new HashMap<>(); for (Player player : Bukkit.getOnlinePlayers()) { - int version = ((CraftPlayer) player).getHandle().getProtocol(); + //int version = ((CraftPlayer) player).getHandle().getProtocol(); + int version = ((CraftPlayer) player).getHandle().playerConnection.networkManager.getVersion(); int players = versions.getOrDefault(version, 0); versions.put(version, players + 1); } @@ -70,8 +80,9 @@ public class VersionsCommand extends CommandBase for (Map.Entry entry : sorted) { int protocol = entry.getKey(); - String pretty = PRETTY_VERSIONS.computeIfAbsent(protocol, x -> Integer.toString(protocol)); - + //String pretty = PRETTY_VERSIONS.computeIfAbsent(protocol, x -> Integer.toString(protocol)); + //HARDCODED + String pretty = "v1.8.9"; UtilPlayer.message(caller, F.main("Version", C.cYellow + pretty + C.cGray + ": " + C.cGreen + entry.getValue() + C.cGray + " players")); @@ -83,7 +94,8 @@ public class VersionsCommand extends CommandBase if (!players.isEmpty()) { Player player = players.get(0); - int protocol = ((CraftPlayer) player).getHandle().getProtocol(); + //int protocol = ((CraftPlayer) player).getHandle().getProtocol(); + int protocol = ((CraftPlayer) player).getHandle().playerConnection.networkManager.getVersion(); String pretty = PRETTY_VERSIONS.computeIfAbsent(protocol, x -> Integer.toString(protocol)); UtilPlayer.message(caller, @@ -95,7 +107,5 @@ public class VersionsCommand extends CommandBase { UtilPlayer.message(caller, F.main("Version", "Invalid argument list.")); } - */ - UtilPlayer.message(caller, F.main("Version", "Nigga im lazy af. TODO: Protocol Support")); } } \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/npc/NpcManager.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/npc/NpcManager.java index 5b754d67..5cd6a190 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/npc/NpcManager.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/npc/NpcManager.java @@ -1,5 +1,56 @@ package mineplex.core.npc; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.EntityInsentient; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; +import org.jooq.Result; +import org.jooq.impl.DSL; + import mineplex.core.MiniPlugin; import mineplex.core.account.permissions.Permission; import mineplex.core.account.permissions.PermissionGroup; @@ -18,27 +69,6 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.database.Tables; import mineplex.database.tables.records.NpcsRecord; import mineplex.serverdata.database.DBPool; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import org.bukkit.*; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity; -import org.bukkit.entity.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.*; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.util.Vector; -import org.jooq.Result; -import org.jooq.impl.DSL; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.*; public class NpcManager extends MiniPlugin { @@ -101,7 +131,6 @@ public class NpcManager extends MiniPlugin require(DisguiseManager.class); - /* try { loadNpcs(); @@ -111,8 +140,6 @@ public class NpcManager extends MiniPlugin e.printStackTrace(); } - */ - generatePermissions(); } diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/punish/Punish.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/punish/Punish.java index 9e866695..1e03e070 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/punish/Punish.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/punish/Punish.java @@ -1,27 +1,10 @@ package mineplex.core.punish; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import mineplex.core.MiniPlugin; -import mineplex.core.account.CoreClient; -import mineplex.core.account.CoreClientManager; -import mineplex.core.account.event.ClientWebResponseEvent; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.common.Constants; -import mineplex.core.common.util.*; -import mineplex.core.common.util.UtilTime.TimeUnit; -import mineplex.core.punish.Command.HistoryCommand; -import mineplex.core.punish.Command.PunishCommand; -import mineplex.core.punish.Command.RulesCommand; -import mineplex.core.punish.Tokens.PunishClientToken; -import mineplex.core.punish.Tokens.PunishmentToken; -import mineplex.core.punish.clans.ClansBanManager; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.serverdata.commands.AddPunishCommand; -import mineplex.serverdata.commands.RemovePunishCommand; -import mineplex.serverdata.commands.ServerCommandManager; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.logging.Level; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Sound; @@ -35,10 +18,34 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.java.JavaPlugin; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; -import java.util.logging.Level; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.event.ClientWebResponseEvent; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.Constants; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +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.punish.Command.HistoryCommand; +import mineplex.core.punish.Command.PunishCommand; +import mineplex.core.punish.Command.RulesCommand; +import mineplex.core.punish.Tokens.PunishClientToken; +import mineplex.core.punish.Tokens.PunishmentToken; +import mineplex.core.punish.clans.ClansBanManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.serverdata.commands.AddPunishCommand; +import mineplex.serverdata.commands.RemovePunishCommand; +import mineplex.serverdata.commands.ServerCommandManager; public class Punish extends MiniPlugin { diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/sound/SoundNotifier.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/sound/SoundNotifier.java index 2032a153..c18db109 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/sound/SoundNotifier.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/sound/SoundNotifier.java @@ -1,6 +1,16 @@ package mineplex.core.sound; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + import com.google.common.collect.Sets; +//TODO: Sound? +//import com.mineplex.spigot.MissingSoundEvent; + +import org.bukkit.event.EventHandler; +import org.bukkit.scheduler.BukkitRunnable; + import mineplex.core.MiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.common.util.UtilServer; @@ -10,11 +20,6 @@ import mineplex.core.slack.SlackTeam; import mineplex.serverdata.Region; import mineplex.serverdata.redis.atomic.RedisStringRepository; import mineplex.serverdata.servers.ServerManager; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; /** * Notifies #pc-sound-logging when we detect a bad sound mapping @@ -73,9 +78,8 @@ public class SoundNotifier extends MiniPlugin } + //TODO: Sound? /* - - TODO: Never hahaha @EventHandler public void onMissingSound(MissingSoundEvent event) { @@ -85,7 +89,7 @@ public class SoundNotifier extends MiniPlugin { _messages.add(message); } - }] + } */ diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/treasure/types/NormalTreasure.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/treasure/types/NormalTreasure.java index 7c349e89..17d065a7 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/treasure/types/NormalTreasure.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/treasure/types/NormalTreasure.java @@ -1,16 +1,56 @@ package mineplex.core.treasure.types; -import mineplex.core.gadget.gadgets.arrowtrail.*; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailBalance; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailBlood; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailConfetti; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailEmerald; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailEnchant; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailMusic; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailShadow; +import mineplex.core.gadget.gadgets.arrowtrail.ArrowTrailStorm; import mineplex.core.gadget.gadgets.balloons.BalloonType; -import mineplex.core.gadget.gadgets.death.*; -import mineplex.core.gadget.gadgets.doublejump.*; -import mineplex.core.gadget.gadgets.item.*; +import mineplex.core.gadget.gadgets.death.DeathBalance; +import mineplex.core.gadget.gadgets.death.DeathBlood; +import mineplex.core.gadget.gadgets.death.DeathEmerald; +import mineplex.core.gadget.gadgets.death.DeathEnchant; +import mineplex.core.gadget.gadgets.death.DeathMusic; +import mineplex.core.gadget.gadgets.death.DeathPinataBurst; +import mineplex.core.gadget.gadgets.death.DeathShadow; +import mineplex.core.gadget.gadgets.death.DeathStorm; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpBalance; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpBlood; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpEmerald; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpEnchant; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpFirecracker; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpMusic; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpShadow; +import mineplex.core.gadget.gadgets.doublejump.DoubleJumpStorm; +import mineplex.core.gadget.gadgets.item.ItemBatGun; +import mineplex.core.gadget.gadgets.item.ItemEtherealPearl; +import mineplex.core.gadget.gadgets.item.ItemFirework; +import mineplex.core.gadget.gadgets.item.ItemFleshHook; +import mineplex.core.gadget.gadgets.item.ItemMelonLauncher; +import mineplex.core.gadget.gadgets.item.ItemPaintballGun; +import mineplex.core.gadget.gadgets.item.ItemTNT; +import mineplex.core.gadget.gadgets.item.ItemTrampoline; import mineplex.core.gadget.gadgets.kitselector.HaloKitSelector; import mineplex.core.gadget.gadgets.kitselector.RainbowDanceKitSelector; import mineplex.core.gadget.gadgets.kitselector.ShimmeringRingKitSelector; import mineplex.core.gadget.gadgets.kitselector.SingleParticleKitSelector; -import mineplex.core.gadget.gadgets.morph.*; -import mineplex.core.gadget.gadgets.mount.types.*; +import mineplex.core.gadget.gadgets.morph.MorphBat; +import mineplex.core.gadget.gadgets.morph.MorphBlock; +import mineplex.core.gadget.gadgets.morph.MorphChicken; +import mineplex.core.gadget.gadgets.morph.MorphCow; +import mineplex.core.gadget.gadgets.morph.MorphEnderman; +import mineplex.core.gadget.gadgets.morph.MorphSkeleton; +import mineplex.core.gadget.gadgets.morph.MorphSlime; +import mineplex.core.gadget.gadgets.morph.MorphVillager; +import mineplex.core.gadget.gadgets.morph.MorphWolf; +import mineplex.core.gadget.gadgets.mount.types.MountCart; +import mineplex.core.gadget.gadgets.mount.types.MountFrost; +import mineplex.core.gadget.gadgets.mount.types.MountMule; +import mineplex.core.gadget.gadgets.mount.types.MountSlime; +import mineplex.core.gadget.gadgets.mount.types.MountUndead; import mineplex.core.gadget.gadgets.outfit.ravesuit.OutfitRaveSuitBoots; import mineplex.core.gadget.gadgets.outfit.ravesuit.OutfitRaveSuitChestplate; import mineplex.core.gadget.gadgets.outfit.ravesuit.OutfitRaveSuitHelmet; @@ -19,9 +59,39 @@ import mineplex.core.gadget.gadgets.outfit.spacesuit.OutfitSpaceSuitBoots; import mineplex.core.gadget.gadgets.outfit.spacesuit.OutfitSpaceSuitChestplate; import mineplex.core.gadget.gadgets.outfit.spacesuit.OutfitSpaceSuitHelmet; import mineplex.core.gadget.gadgets.outfit.spacesuit.OutfitSpaceSuitLeggings; -import mineplex.core.gadget.gadgets.particle.*; +import mineplex.core.gadget.gadgets.particle.ParticleBlood; +import mineplex.core.gadget.gadgets.particle.ParticleCape; +import mineplex.core.gadget.gadgets.particle.ParticleChickenWings; +import mineplex.core.gadget.gadgets.particle.ParticleDeepSeaSwirl; +import mineplex.core.gadget.gadgets.particle.ParticleEmerald; +import mineplex.core.gadget.gadgets.particle.ParticleEnchant; +import mineplex.core.gadget.gadgets.particle.ParticleFairy; +import mineplex.core.gadget.gadgets.particle.ParticleFireRings; +import mineplex.core.gadget.gadgets.particle.ParticleFoot; +import mineplex.core.gadget.gadgets.particle.ParticleFoxTail; +import mineplex.core.gadget.gadgets.particle.ParticleHeart; +import mineplex.core.gadget.gadgets.particle.ParticleInfused; +import mineplex.core.gadget.gadgets.particle.ParticleJetPack; +import mineplex.core.gadget.gadgets.particle.ParticleLegendaryHero; +import mineplex.core.gadget.gadgets.particle.ParticleMusic; +import mineplex.core.gadget.gadgets.particle.ParticlePartyTime; +import mineplex.core.gadget.gadgets.particle.ParticleRain; +import mineplex.core.gadget.gadgets.particle.ParticleRainbowTrail; +import mineplex.core.gadget.gadgets.particle.ParticleWingsAngel; +import mineplex.core.gadget.gadgets.particle.ParticleWingsDemons; +import mineplex.core.gadget.gadgets.particle.ParticleWingsInfernal; +import mineplex.core.gadget.gadgets.particle.ParticleWingsPixie; +import mineplex.core.gadget.gadgets.particle.ParticleWolfTail; +import mineplex.core.gadget.gadgets.particle.ParticleYinYang; import mineplex.core.gadget.gadgets.taunts.EmojiTaunt; import mineplex.core.gadget.gadgets.weaponname.WeaponNameType; +import mineplex.core.gadget.gadgets.wineffect.WinEffectBabyChicken; +import mineplex.core.gadget.gadgets.wineffect.WinEffectEarthquake; +import mineplex.core.gadget.gadgets.wineffect.WinEffectLavaTrap; +import mineplex.core.gadget.gadgets.wineffect.WinEffectLightningStrike; +import mineplex.core.gadget.gadgets.wineffect.WinEffectMrPunchMan; +import mineplex.core.gadget.gadgets.wineffect.WinEffectPartyAnimal; +import mineplex.core.gadget.gadgets.wineffect.WinEffectRiseOfTheElderGuardian; import mineplex.core.gadget.util.CostConstants; import mineplex.core.pet.PetType; import mineplex.core.treasure.reward.RewardRarity; @@ -236,7 +306,6 @@ public class NormalTreasure extends Treasure addGadgetReward(getGadget(ParticleInfused.class), rarity, 10); // Win Effects - /* addGadgetReward(getGadget(WinEffectBabyChicken.class), rarity, 10); addGadgetReward(getGadget(WinEffectLavaTrap.class), rarity, 20); addGadgetReward(getGadget(WinEffectLightningStrike.class), rarity, 20); @@ -245,8 +314,6 @@ public class NormalTreasure extends Treasure addGadgetReward(getGadget(WinEffectEarthquake.class), rarity, 10); addGadgetReward(getGadget(WinEffectPartyAnimal.class), rarity, 10); - */ - // Titles addTitleReward("ayyye", rarity, 25); addTitleReward("ameno", rarity, 15); diff --git a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/twofactor/TwoFactorAuth.java b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/twofactor/TwoFactorAuth.java index d9acac60..14fb22ae 100644 --- a/Plugins[Modified]/Mineplex.Core/src/mineplex/core/twofactor/TwoFactorAuth.java +++ b/Plugins[Modified]/Mineplex.Core/src/mineplex/core/twofactor/TwoFactorAuth.java @@ -1,18 +1,11 @@ package mineplex.core.twofactor; -import com.warrenstrange.googleauth.GoogleAuthenticator; -import com.warrenstrange.googleauth.GoogleAuthenticatorConfig; -import mineplex.core.Managers; -import mineplex.core.MiniClientPlugin; -import mineplex.core.ReflectivelyCreateMiniPlugin; -import mineplex.core.account.CoreClientManager; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.command.CommandBase; -import mineplex.core.common.util.*; -import mineplex.core.recharge.Recharge; -import mineplex.serverdata.commands.TwoFactorResetCommand; -import mineplex.serverdata.database.DBPool; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -22,12 +15,38 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryEvent; -import org.bukkit.event.player.*; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.map.MapRenderer; import org.bukkit.map.MapView; -import java.util.*; +import com.warrenstrange.googleauth.GoogleAuthenticator; +import com.warrenstrange.googleauth.GoogleAuthenticatorConfig; + +import mineplex.core.Managers; +import mineplex.core.MiniClientPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.BukkitFuture; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayerBase; +import mineplex.core.common.util.UtilServer; +import mineplex.core.recharge.Recharge; +import mineplex.serverdata.commands.TwoFactorResetCommand; +import mineplex.serverdata.database.DBPool; @ReflectivelyCreateMiniPlugin public class TwoFactorAuth extends MiniClientPlugin @@ -194,7 +213,6 @@ public class TwoFactorAuth extends MiniClientPlugin @EventHandler public void onJoin(PlayerJoinEvent event) { - /* Player player = event.getPlayer(); TwoFactorData data = Get(player); @@ -218,8 +236,7 @@ public class TwoFactorAuth extends MiniClientPlugin { runSync(() -> setup2FA(event.getPlayer())); } - - */ + } } @EventHandler diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/pom.xml b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/pom.xml new file mode 100644 index 00000000..2eadc0ad --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + + com.mineplex + mineplex-app + dev-SNAPSHOT + ../app.xml + + + DDoSProtectionSwitcher + mineplex-ddosprotectionswitcher + + + + com.google.code.gson + gson + + + javax.mail + mail + + + org.apache.httpcomponents + httpclient + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + mineplex.ddos.DDoSProtectionSwitcher + + + + + + + diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/DDoSProtectionSwitcher.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/DDoSProtectionSwitcher.java new file mode 100644 index 00000000..9bcaaf2d --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/DDoSProtectionSwitcher.java @@ -0,0 +1,325 @@ +package mineplex.ddos; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMessage.RecipientType; + +import mineplex.ddos.api.ApiDeleteCall; +import mineplex.ddos.api.ApiGetCall; +import mineplex.ddos.api.ApiPostCall; +import mineplex.ddos.api.ApiPutCall; +import mineplex.ddos.api.token.DnsRecord; +import mineplex.ddos.api.token.DomainRecords; + +public class DDoSProtectionSwitcher +{ + private static DnsMadeEasyRepository _repository = null; + private static HashSet _processes = new HashSet(); + + public static void main(String args[]) + { + try + { + Class.forName("com.mysql.jdbc.Driver"); + } + catch (ClassNotFoundException e1) + { + e1.printStackTrace(); + } + + _repository = new DnsMadeEasyRepository(); + DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + + //while (true) + //{ + //if (_repository.switchToDDOSProt()) + //{ + + System.out.println("Starting DDoS Protection Switch at " + dateFormat.format(new Date())); + + DomainRecords records = new ApiGetCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, + "/records", "").Execute(DomainRecords.class); + List recordsToDelete = new ArrayList(); + List recordsToAdd = new ArrayList(); + List recordsToModify = new ArrayList(); + + // Switch on ddos protection + for (DnsRecord record : records.data) + { + if (record.type.equalsIgnoreCase("A")) + { + if (record.name.equalsIgnoreCase("neustar")) + { + record.name = "us"; + recordsToModify.add(record); + } + else if (record.name.equalsIgnoreCase("us")) + { + record.name = "us2"; + recordsToModify.add(record); + } + else if (record.name.equalsIgnoreCase("eu")) + { + record.name = "eu2"; + recordsToModify.add(record); + } + } + } + + if (recordsToAdd.size() > 0) + { + new ApiPostCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records/", "createMulti") + .Execute(records); + System.out.println("Created " + recordsToAdd.size() + " records."); + } + + if (recordsToModify.size() > 0) + { + new ApiPutCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records/", "updateMulti") + .Execute(recordsToModify); + System.out.println("Modified " + recordsToModify.size() + " records."); + } + + if (recordsToDelete.size() > 0) + { + StringBuilder idBuilder = new StringBuilder(); + + for (DnsRecord record : recordsToDelete) + { + if (idBuilder.length() != 0) + idBuilder.append("&"); + + idBuilder.append("ids=" + record.id); + } + + new ApiDeleteCall("https://api.dnsmadeeasy.com/V2.0/dns/managed/", 962728, "/records?" + + idBuilder.toString()).Execute(); + System.out.println("Deleted " + recordsToDelete.size() + " records."); + } +/* + // Switching US Bungees + switchServer("10.35.74.130", "108.178.20.166", "108.163.222.202", "108.178.20.165", "108.163.222.201"); + switchServer("10.35.74.132", "108.163.217.110", "108.178.44.50", "108.163.217.109", "108.178.44.49"); + switchServer("10.35.74.142", "108.178.16.90", "108.178.16.90", "108.178.16.89", "108.178.16.89"); + switchServer("10.35.74.135", "108.163.254.134", "108.178.16.106", "108.163.254.133", "108.178.16.105"); + switchServer("10.35.74.137", "108.163.216.250", "108.178.34.162", "108.163.216.249", "108.178.34.161"); + switchServer("10.35.74.147", "108.163.216.106", "184.154.39.126", "108.163.216.105", "184.154.39.125"); + switchServer("10.35.74.143", "184.154.215.170", "108.178.17.6", "184.154.215.169", "108.178.17.5"); + switchServer("10.35.74.145", "96.127.174.206", "108.178.7.118", "96.127.174.205", "108.178.7.117"); + switchServer("10.35.74.144", "184.154.127.10", "184.154.39.154", "184.154.127.9", "184.154.39.153"); + switchServer("10.35.74.146", "96.127.174.146", "108.178.16.26", "96.127.174.145", "108.178.16.25"); + switchServer("10.35.74.149", "108.178.7.206", "107.6.158.198", "108.178.7.205", "107.6.158.197"); + switchServer("10.35.74.136", "184.154.39.146", "184.154.13.218", "184.154.39.145", "184.154.13.217"); + switchServer("10.35.74.139", "108.163.217.250", "108.178.44.134", "108.163.217.249", "108.178.44.133"); + switchServer("10.35.74.140", "69.175.15.242", "108.163.216.38", "69.175.15.241", "108.163.216.37"); + switchServer("10.35.74.141", "107.6.129.126", "96.127.182.218", "107.6.129.125", "96.127.182.217"); + switchServer("10.35.74.134", "108.163.222.174", "108.163.216.82", "108.163.222.173", "108.163.216.81"); + switchServer("10.32.214.248", "108.178.34.118", "107.6.129.170", "108.178.34.117", "107.6.129.169"); + switchServer("10.32.214.250", "69.175.4.38", "107.6.129.250", "69.175.4.37", "107.6.129.249"); + switchServer("10.32.214.249", "107.6.158.78", "184.154.13.38", "107.6.158.77", "184.154.13.37"); + switchServer("10.32.214.247", "184.154.13.118", "108.163.242.98", "184.154.13.117", "108.163.242.97"); +*/ + /* + // Switching EU Bungees + switchServer("10.82.2.202", "107.6.176.194", "107.6.176.34", "107.6.176.193", "107.6.176.33"); + switchServer("10.82.2.204", "107.6.176.122", "107.6.176.50", "107.6.176.121", "107.6.176.49"); + switchServer("10.82.2.206", "107.6.176.166", "107.6.176.126", "107.6.176.165", "107.6.176.125"); + switchServer("10.83.27.77", "107.6.176.14", "107.6.176.98", "107.6.176.13", "107.6.176.97"); + switchServer("10.82.2.225", "107.6.176.114", "107.6.176.58", "107.6.176.113", "107.6.176.57"); + switchServer("10.82.2.227", "107.6.176.26", "107.6.176.46", "107.6.176.25", "107.6.176.45"); + switchServer("10.82.2.228", "107.6.176.110", "107.6.176.70", "107.6.176.109", "107.6.176.69"); + switchServer("10.82.2.226", "107.6.176.138", "107.6.176.234", "107.6.176.137", "107.6.176.233"); + */ + //sendMail(); + //} + + int processWaits = 0; + + while (_processes.size() > 0) + { + for (Iterator iterator = _processes.iterator(); iterator.hasNext();) + { + ProcessRunner pr = iterator.next(); + + try + { + pr.join(100); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + if (pr.isDone()) + iterator.remove(); + } + + if (_processes.size() > 0) + { + try + { + Thread.sleep(6000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + if (processWaits >= 60) + { + System.out.println("Killing stale processes."); + + for (Iterator iterator = _processes.iterator(); iterator.hasNext();) + { + iterator.next().abort(); + iterator.remove(); + } + } + + processWaits++; + } + + processWaits = 0; + + try + { + Thread.sleep(60000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + //} + /* + * // Switch off ddos protection for (DnsRecord record : records.data) { + * if (record.type.equalsIgnoreCase("CNAME")) { if + * (record.name.equalsIgnoreCase("eu")) recordsToDelete.add(record); } + * else if (record.type.equalsIgnoreCase("A")) { if + * (record.name.equalsIgnoreCase("us")) { record.name = "neustar"; + * recordsToModify.add(record); } else if + * (record.name.equalsIgnoreCase("us2")) { record.name = "us"; + * recordsToModify.add(record); } else if + * (record.name.equalsIgnoreCase("eu2")) { record.name = "eu"; + * recordsToModify.add(record); } } } + * + * + * + * recordsToAdd.add(new CNameRecord("eu", "us", 300)); + */ + } + + private static void sendMail() + { + Message message = new MimeMessage(getSession()); + + try + { + message.addRecipient(RecipientType.TO, new InternetAddress("ultrasupport@neustar.biz")); + message.addFrom(new InternetAddress[] { new InternetAddress("it@mineplex.com") }); + + message.setSubject("Start Mitigation Incident"); + message.setText("We need to start mitigation.\n\n" + + "Jonathan Williams\n" + + "Director of Gaming Software Development\n" + + "Mineplex, LLC\n" + + "PH: 805.231.0407\n" + + "http://www.mineplex.com"); + + + Transport.send(message); + + System.out.println("Sent Neustar Mitigation Email at " + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date())); + } + catch (AddressException e) + { + e.printStackTrace(); + } + catch (MessagingException e) + { + e.printStackTrace(); + } + } + + private static Session getSession() + { + Authenticator authenticator = new Authenticator(); + + Properties properties = new Properties(); + properties.setProperty("mail.smtp.submitter", authenticator.getPasswordAuthentication().getUserName()); + + properties.setProperty("mail.smtp.host", "smtp.fatcow.com"); + properties.setProperty("mail.smtp.socketFactory.port", "465"); + properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + properties.setProperty("mail.smtp.auth", "true"); + properties.setProperty("mail.smtp.port", "465"); + + return Session.getInstance(properties, authenticator); + } + + private static void switchServer(final String privateIp, String currentIp, String newIp, String currentGateway, + String newGateway) + { + String cmd = "/usr/bin/ssh"; + String args = "-to StrictHostKeyChecking=no -o ServerAliveInterval=10 mineplex@" + privateIp + " -p 5191"; + String remoteCmd = "\"sh /home/mineplex/config/switchBungeeIpRemote.sh"; + String remoteCmdEnd = "\""; + + ProcessRunner pr = new ProcessRunner(new String[] { cmd, args, remoteCmd, currentIp, newIp, + currentGateway, newGateway, remoteCmdEnd }); + pr.start(new GenericRunnable() + { + public void run(Boolean error) + { + if (error) + System.out.println("[" + privateIp + "] Errored!"); + else + System.out.println("[" + privateIp + "] Switched!"); + } + }); + + try + { + pr.join(500); + } + catch (InterruptedException e1) + { + e1.printStackTrace(); + } + + if (!pr.isDone()) + _processes.add(pr); + } + + private static class Authenticator extends javax.mail.Authenticator + { + private PasswordAuthentication authentication; + + public Authenticator() + { + String username = "it@mineplex.com"; + String password = "BearT4bl312ust"; + authentication = new PasswordAuthentication(username, password); + } + + protected PasswordAuthentication getPasswordAuthentication() + { + return authentication; + } + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/DnsMadeEasyRepository.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/DnsMadeEasyRepository.java new file mode 100644 index 00000000..aebe2bde --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/DnsMadeEasyRepository.java @@ -0,0 +1,128 @@ +package mineplex.ddos; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; + +public class DnsMadeEasyRepository +{ + // Yip Yip actual IP because if null route happens we can't resolve the HOSTNAME DERP FACE DEFEK7!!! -defek7 + private String _connectionString = "jdbc:mysql://10.35.74.133:3306/BungeeServers?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS bungeeOnlineStatus (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(40), online BOOLEAN NOT NULL DEFAULT 0, updated LONG, us BOOLEAN NOT NULL DEFAULT 1, lastOnline LONG, PRIMARY KEY (id), UNIQUE INDEX addressIndex(address));"; + private static String SELECT_SERVERS = "SELECT updated, lastOnline, us, now() FROM bungeeOnlineStatus;"; + + public void initialize() + { + Connection connection = null; + PreparedStatement preparedStatement = null; + + try + { + connection = DriverManager.getConnection(_connectionString, _userName, _password); + + // Create table + preparedStatement = connection.prepareStatement(CREATE_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + if (connection != null) + { + try + { + connection.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public boolean switchToDDOSProt() + { + Connection connection = null; + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + int countOffline = 0; + + try + { + connection = DriverManager.getConnection(_connectionString, _userName, _password); + + preparedStatement = connection.prepareStatement(SELECT_SERVERS); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + long current = dateFormat.parse(resultSet.getString(4)).getTime(); + long updated = dateFormat.parse(resultSet.getString(1)).getTime(); + long lastOnline = dateFormat.parse(resultSet.getString(2)).getTime(); + + if (current - updated < 70000 && current - lastOnline > 660000) + countOffline++; + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + if (connection != null) + { + try + { + connection.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + //if (countOffline > 5) + System.out.println(countOffline + " offline bungees."); + + return true; + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/GenericRunnable.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/GenericRunnable.java new file mode 100644 index 00000000..dd6cc1a7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/GenericRunnable.java @@ -0,0 +1,6 @@ +package mineplex.ddos; + +public interface GenericRunnable +{ + void run(T t); +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/ProcessRunner.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/ProcessRunner.java new file mode 100644 index 00000000..744cab76 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/ProcessRunner.java @@ -0,0 +1,81 @@ +package mineplex.ddos; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class ProcessRunner extends Thread +{ + private ProcessBuilder _processBuilder; + private Process _process; + private GenericRunnable _runnable; + + boolean _done = false; + Boolean _error = false; + + ProcessRunner(String[] args) + { + super("ProcessRunner " + args); + _processBuilder = new ProcessBuilder(args); + } + + public void run() + { + try + { + _process = _processBuilder.start(); + _process.waitFor(); + + BufferedReader reader=new BufferedReader(new InputStreamReader(_process.getInputStream())); + String line = reader.readLine(); + + while(line != null) + { + if (line.equals("255")) + _error = true; + + line=reader.readLine(); + } + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + finally + { + _done = true; + + if (_runnable != null) + _runnable.run(_error); + } + } + + public void start(GenericRunnable runnable) + { + super.start(); + + _runnable = runnable; + } + + public int exitValue() throws IllegalStateException + { + if (_process != null) + { + return _process.exitValue(); + } + + throw new IllegalStateException("Process not started yet"); + } + + public boolean isDone() + { + return _done; + } + + public void abort() + { + if (!isDone()) + { + _process.destroy(); + } + } + } diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiDeleteCall.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiDeleteCall.java new file mode 100644 index 00000000..5e91aab8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiDeleteCall.java @@ -0,0 +1,19 @@ +package mineplex.ddos.api; + +import org.apache.http.client.methods.HttpDelete; + +public class ApiDeleteCall extends DnsMadeEasyApiCallBase +{ + public ApiDeleteCall(String apiUrl, int domainId, String category) + { + super(apiUrl, domainId, category); + } + + public void Execute() + { + HttpDelete request = new HttpDelete(ApiUrl + DomainId + Category); + System.out.println(request.getURI().toString()); + + System.out.println(execute(request)); + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiGetCall.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiGetCall.java new file mode 100644 index 00000000..cc5e19b2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiGetCall.java @@ -0,0 +1,35 @@ +package mineplex.ddos.api; + +import java.lang.reflect.Type; + +import org.apache.http.client.methods.HttpGet; + +import com.google.gson.Gson; + +public class ApiGetCall extends DnsMadeEasyApiCallBase +{ + private String _action; + + public ApiGetCall(String apiUrl, int domainId, String category, String action) + { + super(apiUrl, domainId, category); + + _action = action; + } + + public void Execute() + { + HttpGet request = new HttpGet(ApiUrl + DomainId + Category + _action); + + System.out.println(execute(request)); + } + + public T Execute(Type returnType) + { + HttpGet request = new HttpGet(ApiUrl + DomainId + Category + _action); + + String response = execute(request); + System.out.println(response); + return new Gson().fromJson(response, returnType); + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiPostCall.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiPostCall.java new file mode 100644 index 00000000..ec1c119d --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiPostCall.java @@ -0,0 +1,79 @@ +package mineplex.ddos.api; + +import java.lang.reflect.Type; + +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +public class ApiPostCall extends DnsMadeEasyApiCallBase +{ + private String _action; + + public ApiPostCall(String apiUrl, int domainId, String category, String action) + { + super(apiUrl, domainId, category); + + _action = action; + } + + public void Execute(Object argument) + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(ApiUrl + DomainId + Category + _action); + + System.out.println(request.getURI().toString()); + + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPostCall(Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + System.out.println(execute(request)); + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(ApiUrl + DomainId + Category + _action); + System.out.println(request.getURI().toString()); + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPostCall(Type, Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + String response = execute(request); + System.out.println(response); + return new Gson().fromJson(response, returnType); + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiPutCall.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiPutCall.java new file mode 100644 index 00000000..e5cf95b5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/ApiPutCall.java @@ -0,0 +1,80 @@ +package mineplex.ddos.api; + +import java.lang.reflect.Type; + +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +public class ApiPutCall extends DnsMadeEasyApiCallBase +{ + private String _action; + + public ApiPutCall(String apiUrl, int domainId, String category, String action) + { + super(apiUrl, domainId, category); + + _action = action; + } + + public void Execute(Object argument) + { + Gson gson = new Gson(); + HttpPut request = new HttpPut(ApiUrl + DomainId + Category + _action); + + System.out.println(request.getURI().toString()); + + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPutCall(Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + System.out.println(execute(request)); + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + Gson gson = new Gson(); + HttpPut request = new HttpPut(ApiUrl + DomainId + Category + _action); + System.out.println(request.getURI().toString()); + try + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + catch (Exception exception) + { + System.out.println("Error executing ApiPutCall(Type, Object): \n" + exception.getMessage()); + + for (StackTraceElement trace : exception.getStackTrace()) + { + System.out.println(trace); + } + } + + String response = execute(request); + System.out.println(response); + return new Gson().fromJson(response, returnType); + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/DnsMadeEasyApiCallBase.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/DnsMadeEasyApiCallBase.java new file mode 100644 index 00000000..f21f48f2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/DnsMadeEasyApiCallBase.java @@ -0,0 +1,140 @@ +package mineplex.ddos.api; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Hex; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; + +public abstract class DnsMadeEasyApiCallBase +{ + protected String ApiUrl = "http://api.dnsmadeeasy.com/V2.0/dns/managed/"; + protected int DomainId = 962728; + protected String Category = "/records/"; + + public DnsMadeEasyApiCallBase(String apiUrl, int domainId, String category) + { + ApiUrl = apiUrl; + DomainId = domainId; + Category = category; + } + + protected String execute(HttpRequestBase request) + { + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("https", 80, PlainSocketFactory.getSocketFactory())); + + PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(schemeRegistry); + connectionManager.setMaxTotal(200); + connectionManager.setDefaultMaxPerRoute(20); + + HttpClient httpClient = new DefaultHttpClient(connectionManager); + InputStream in = null; + String response = ""; + + try + { + String timeStamp = getServerTime(); + SecretKeySpec keySpec = new SecretKeySpec("8c9af8cc-d306-4df3-8de8-944deafa8239".getBytes(), "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(keySpec); + byte[] hashBytes = mac.doFinal((timeStamp + "").getBytes()); + Hex.encodeHexString(hashBytes); + + request.addHeader("x-dnsme-apiKey", "610e21ee-4250-4b55-b637-a1fcc3847850"); + request.addHeader("x-dnsme-requestDate", timeStamp + ""); + request.addHeader("x-dnsme-hmac", Hex.encodeHexString(hashBytes)); + request.addHeader("Content-Type", "application/json"); + + HttpResponse httpResponse = httpClient.execute(request); + + if (httpResponse != null) + { + in = httpResponse.getEntity().getContent(); + response = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("DnsMadeEasyApiCall Error:\n" + ex.getMessage()); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return response; + } + + protected String getServerTime() + { + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + return dateFormat.format(calendar.getTime()); + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try + { + while ((line = reader.readLine()) != null) + { + sb.append(line + "\n"); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + finally + { + try + { + is.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/ARecord.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/ARecord.java new file mode 100644 index 00000000..afa7f5a5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/ARecord.java @@ -0,0 +1,14 @@ +package mineplex.ddos.api.token; + +public class ARecord extends DnsRecord +{ + public ARecord(String recordName, String ip, int recordTtl) + { + name = recordName; + value = ip; + ttl = recordTtl; + + type = "A"; + gtdLocation = "DEFAULT"; + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/CNameRecord.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/CNameRecord.java new file mode 100644 index 00000000..0f982928 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/CNameRecord.java @@ -0,0 +1,14 @@ +package mineplex.ddos.api.token; + +public class CNameRecord extends DnsRecord +{ + public CNameRecord(String recordName, String ip, int recordTtl) + { + name = recordName; + value = ip; + ttl = recordTtl; + + type = "CNAME"; + gtdLocation = "DEFAULT"; + } +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/DnsRecord.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/DnsRecord.java new file mode 100644 index 00000000..94f32ae5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/DnsRecord.java @@ -0,0 +1,11 @@ +package mineplex.ddos.api.token; + +public class DnsRecord +{ + public int id; + public String name; + public String type; + public String value; + public String gtdLocation; + public int ttl; +} diff --git a/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/DomainRecords.java b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/DomainRecords.java new file mode 100644 index 00000000..fffc657d --- /dev/null +++ b/Plugins[Modified]/Mineplex.DDoSProtectionSwitcher/src/mineplex/ddos/api/token/DomainRecords.java @@ -0,0 +1,11 @@ +package mineplex.ddos.api.token; + +import java.util.List; + +public class DomainRecords +{ + public List data; + public int page; + public int totalPage; + public int totalRecords; +} diff --git a/Plugins[Modified]/Mineplex.Database/src/jOOQConfig.xml b/Plugins[Modified]/Mineplex.Database/src/jOOQConfig.xml index c3c6b785..42a0f94f 100644 --- a/Plugins[Modified]/Mineplex.Database/src/jOOQConfig.xml +++ b/Plugins[Modified]/Mineplex.Database/src/jOOQConfig.xml @@ -3,9 +3,9 @@ com.mysql.jdbc.Driver - jdbc:mysql://127.0.0.1:3306 - root - root + jdbc:mysql://10.35.74.133:3306 + MonetaryPulitzer + MaprebruvUsw6Fre diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/plugin.yml b/Plugins[Modified]/Mineplex.EnjinTranslator/plugin.yml new file mode 100644 index 00000000..ef3eac20 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/plugin.yml @@ -0,0 +1,12 @@ +name: EnjinTranslator +main: mineplex.enjinTranslator.EnjinTranslator +version: 0.1 +commands: + enjin_mineplex: + description: Translates enjin commands to mineplex. + usage: Don't use it, you get kicked. + aliases: + pull: + description: Translates enjin commands to mineplex. + usage: Don't use it, you get kicked. + aliases: \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/pom.xml b/Plugins[Modified]/Mineplex.EnjinTranslator/pom.xml new file mode 100644 index 00000000..bb8ce596 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + EnjinTranslator + mineplex-enjintranslator + + + + ${project.groupId} + mineplex-core + ${project.version} + + + diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/Enjin.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/Enjin.java new file mode 100644 index 00000000..bbd8864e --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/Enjin.java @@ -0,0 +1,365 @@ +package mineplex.enjinTranslator; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Date; +import java.util.UUID; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.account.permissions.PermissionGroupHelper; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.Callback; +import mineplex.core.donation.DonationManager; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.powerplayclub.PowerPlayClubRepository; +import mineplex.core.punish.Category; +import mineplex.core.punish.Punish; +import mineplex.core.server.util.TransactionResponse; +import mineplex.core.website.WebsiteLinkManager; +import mineplex.enjinTranslator.purchase.PurchaseManager; + +public class Enjin extends MiniPlugin implements CommandExecutor +{ + private CoreClientManager _clientManager; + private DonationManager _donationManager; + private InventoryManager _inventoryManager; + private PurchaseManager _purchaseManager; + private PowerPlayClubRepository _powerPlayClubRepository; + private Punish _punish; + + private static Object _commandLock = new Object(); + + public long _lastPoll = System.currentTimeMillis() - 120000; + + private SimpleDateFormat _dateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss"); + + public Enjin(EnjinTranslator plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager) + { + super("Enjin", plugin); + + _clientManager = clientManager; + _donationManager = donationManager; + _inventoryManager = inventoryManager; + _punish = new Punish(plugin, clientManager); + + _purchaseManager = new PurchaseManager(plugin); + _powerPlayClubRepository = new PowerPlayClubRepository(plugin, clientManager, donationManager); + require(WebsiteLinkManager.class); + + plugin.getCommand("enjin_mineplex").setExecutor(this); + plugin.getCommand("pull").setExecutor(this); + } + + @Override + public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) + { + synchronized (_commandLock) + { + try + { + if (sender instanceof Player) + ((Player) sender).kickPlayer("Like bananas? I don't. Here take these and go have fun."); + + if (label.equalsIgnoreCase("enjin_mineplex")) + { + final UUID uuid; + try + { + uuid = UUID.fromString(args[1]); + } + catch (IllegalArgumentException e) + { + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + args[1] + "; invalid UUID."); + return true; + } + + _clientManager.loadClientByUUID(uuid, client -> + { + if (client == null) + { + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + uuid + ", isn't in our database."); + } + else + { + final String name = client.getName(); + + if (args[0].equalsIgnoreCase("chargeback")) + { + _punish.AddPunishment(name, Category.Other, "Chargeback", "Strutt20", 1, true, -1, true); + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " was banned for charging back!"); + return; + } + + if (!checkForClansPurchase(args, name, client)) + { + if (!checkForBoosterPurchase(args, name, uuid, client)) + { + if (!checkForCoinPurchase(args, name, uuid, client)) + { + if (!checkForRankPurchase(args, name, uuid, client)) + { + if (!checkForPurchase(args, name, client)) + { + if (!checkForPowerPlayClub(args, name, uuid, client)) + { + StringBuilder sb = new StringBuilder(); + + for (String arg : args) + { + sb.append(arg + " "); + } + + System.out.println("Received Command : " + sb.toString()); + } + } + } + } + } + } + } + }); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + + try + { + Thread.sleep(20); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + return true; + } + + protected boolean checkForRankPurchase(String[] args, final String name, final UUID playerUUID, final CoreClient client) + { + if (args.length != 3 || !args[0].equalsIgnoreCase("rank")) + { + return false; + } + + PermissionGroup c = PermissionGroup.getGroup(args[2]).orElse(PermissionGroupHelper.getGroupFromLegacy(args[2])); + if (c == null) + { + return false; + } + final PermissionGroup rank = PermissionGroup.valueOf(args[2]); + + _clientManager.loadClientByName(name, loadedClient -> + { + if (rank == PermissionGroup.PLAYER || loadedClient.getPrimaryGroup() == PermissionGroup.PLAYER || !loadedClient.getPrimaryGroup().inheritsFrom(rank)) + { + _clientManager.setPrimaryGroup(client.getAccountId(), rank, () -> _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), rank.name() + "Permanent", 1, true)); + + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + rank.name() + " " + "permanently."); + } + else + { + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " DENIED INFERIOR " + rank.name() + " " + "permanently."); + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), rank.name() + " Permanent", 1, false); + } + }); + + return true; + } + + protected boolean checkForPurchase(String[] args, final String name, final CoreClient client) + { + if (args.length < 3 || !args[0].equalsIgnoreCase("purchase")) + return false; + + final int amount = Integer.parseInt(args[2]); + String tempName = args[4]; + + for (int i = 5; i < args.length; i++) + { + tempName += " " + args[i]; + } + + final String packageName = tempName; + + _donationManager.purchaseUnknownSalesPackage(client, amount == 1 ? packageName : packageName + " " + amount, GlobalCurrency.GEM, 0, false, data -> + { + if (data == TransactionResponse.Success) + { + _inventoryManager.addItemToInventoryForOffline(new Callback() + { + public void run(Boolean success) + { + if (success) + { + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), packageName, amount, true); + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " " + packageName + "."); + } + else + { + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + packageName + ". Queuing for run later."); + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), packageName, amount, false); + } + } + }, client.getAccountId(), packageName, amount); + } + else + { + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + amount + ". Queuing for run later."); + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), packageName, amount, false); + } + }); + + return true; + } + + protected boolean checkForCoinPurchase(String[] args, final String name, final UUID playerUUID, final CoreClient client) + { + if (args.length != 3 || !args[0].equalsIgnoreCase("coin")) + return false; + + final int amount = Integer.parseInt(args[2]); + + _donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, client, "purchase", amount, response -> + { + if (response) + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " coins."); + else + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + amount + " coins. Queuing for run later."); + + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), "Coins", amount, response); + }); + + return true; + } + + protected boolean checkForBoosterPurchase(String[] args, final String name, final UUID playerUUID, final CoreClient client) + { + if (args.length != 3 || !args[0].equalsIgnoreCase("booster")) + return false; + + final int amount = Integer.parseInt(args[2]); + + _inventoryManager.addItemToInventoryForOffline(new Callback() + { + public void run(Boolean response) + { + if (response) + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " gem boosters."); + else + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + amount + " gem boosters. Queuing for run later."); + + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), "Gem Boosters", amount, response); + } + }, client.getAccountId(), "Game Booster", amount); + + return true; + } + + protected boolean checkForPowerPlayClub(String[] args, final String name, final UUID playerUUID, final CoreClient client) + { + if (args.length < 5 || !args[0].equalsIgnoreCase("powerplayclub")) + return false; + + if (args[2].equalsIgnoreCase("add")) + { + boolean bc = args.length > 5 && args[5].equalsIgnoreCase("bc"); + String[] splitDate = args[3].split("/"); + LocalDate date; + if (bc) + { + date = LocalDate.of(2000 + Integer.parseInt(splitDate[2]), Integer.parseInt(splitDate[1]), Integer.parseInt(splitDate[0])); + } + else + { + date = LocalDate.of(Integer.parseInt(splitDate[2]), Integer.parseInt(splitDate[0]), Integer.parseInt(splitDate[1])); + } + + String duration = args[4]; + + _powerPlayClubRepository.addSubscription(client.getAccountId(), date, duration); + + } + else if (args[2].equalsIgnoreCase("cancel")) + { + // TODO: cancel it in our logs? I don't think this is necessary. + } + + return false; + } + + protected boolean checkForClansPurchase(String[] args, final String name, final CoreClient client) + { + if (args.length >= 3 && args[0].equalsIgnoreCase("clansBanner")) + { + String purchase = "Clan Banner Usage"; + if (args[2].equalsIgnoreCase("true")) + { + purchase = "Clan Banner Editor"; + } + final String packageName = purchase; + + _donationManager.purchaseUnknownSalesPackage(client, packageName, GlobalCurrency.GEM, 0, false, data -> + { + if (data == TransactionResponse.Success) + { + _inventoryManager.addItemToInventoryForOffline(new Callback() + { + public void run(Boolean success) + { + if (success) + { + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), packageName, 1, true); + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received their " + packageName + " access."); + } + else + { + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + packageName + ". Queuing for run later."); + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), packageName, 1, false); + } + } + }, client.getAccountId(), packageName, 1); + } + else + { + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " 1" + ". Queuing for run later."); + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), packageName, 1, false); + } + }); + //enjin_mineplex clansBanner AlexTheCoder true + return true; + } + if (args.length >= 4 && args[0].equalsIgnoreCase("clansAmplifier")) + { + //enjin_mineplex clansAmplifier AlexTheCoder 20 1 + final String item = "Rune Amplifier " + args[2]; + final int amount = Integer.parseInt(args[3]); + + _inventoryManager.addItemToInventoryForOffline(new Callback() + { + public void run(Boolean response) + { + if (response) + System.out.println("[" + _dateFormat.format(new Date()) + "] " + name + " received " + amount + " rune amplifiers."); + else + System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + " " + amount + " rune amplifiers. Queuing for run later."); + + _purchaseManager.addAccountPurchaseToQueue(client.getAccountId(), item, amount, response); + } + }, client.getAccountId(), item, amount); + } + + return false; + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinItem.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinItem.java new file mode 100644 index 00000000..4628e18b --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinItem.java @@ -0,0 +1,23 @@ +package mineplex.enjinTranslator; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +public class EnjinItem +{ + public String item_name; + public double item_price; + public int item_id; + public Map variables = new HashMap(); + + public void logInfoToConsole() + { + System.out.println("item_id : " + item_id + ", item_name : " + item_name + ", item_price : " + item_price); + + for (Entry variable : variables.entrySet()) + { + System.out.println("key : " + variable.getKey() + ", value : " + variable.getValue()); + } + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinPurchase.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinPurchase.java new file mode 100644 index 00000000..a7ccf1f2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinPurchase.java @@ -0,0 +1,27 @@ +package mineplex.enjinTranslator; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +public class EnjinPurchase +{ + private static SimpleDateFormat _dateFormat = new SimpleDateFormat(); + + public EnjinUser user; + public long purchase_date; + public String currency; + public String character; + public List items; + + public void logInfoToConsole() + { + user.logInfoToConsole(); + System.out.println(" MC Character : " + character + ", purchase_date : " + _dateFormat.format(new Date(purchase_date)) + ", currency : " + currency); + + for (EnjinItem item : items) + { + item.logInfoToConsole(); + } + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinTranslator.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinTranslator.java new file mode 100644 index 00000000..420388c7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinTranslator.java @@ -0,0 +1,42 @@ +package mineplex.enjinTranslator; + +import mineplex.core.common.Constants; +import mineplex.core.account.CoreClientManager; +import mineplex.core.command.CommandCenter; +import mineplex.core.donation.DonationManager; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.updater.Updater; +import org.bukkit.plugin.java.JavaPlugin; + +import static mineplex.core.Managers.require; + +public class EnjinTranslator extends JavaPlugin +{ + @Override + public void onEnable() + { + getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS); + getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY)); + saveConfig(); + + //Static Modules + CommandCenter.Initialize(this); + + //Core Modules + CoreClientManager clientManager = new CoreClientManager(this); + CommandCenter.Instance.setClientManager(clientManager); + + DonationManager donationManager = require(DonationManager.class); + + //Main Modules + new Enjin(this, clientManager, donationManager, new InventoryManager(this, clientManager)); + + require(Updater.class); + } + + public String GetWebServerAddress() + { + + return getConfig().getString(Constants.WEB_CONFIG_KEY); + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinUser.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinUser.java new file mode 100644 index 00000000..5fd4ac3d --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/EnjinUser.java @@ -0,0 +1,12 @@ +package mineplex.enjinTranslator; + +public class EnjinUser +{ + public int user_id; + public String username; + + public void logInfoToConsole() + { + System.out.println("user_id : " + user_id + ", username : " + username); + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/QueuedCommand.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/QueuedCommand.java new file mode 100644 index 00000000..c27e7275 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/QueuedCommand.java @@ -0,0 +1,20 @@ +package mineplex.enjinTranslator; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class QueuedCommand +{ + public CommandSender Sender; + public Command Command; + public String Label; + public String[] Args; + + public QueuedCommand(CommandSender sender, Command command, String label, String...args) + { + Sender = sender; + Command = command; + Label = label; + Args = args; + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/TempRepository.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/TempRepository.java new file mode 100644 index 00000000..91ddd00c --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/TempRepository.java @@ -0,0 +1,24 @@ +package mineplex.enjinTranslator; + +import mineplex.core.database.MinecraftRepository; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class TempRepository extends RepositoryBase +{ + private static String INSERT_CLIENT_INVENTORY = "INSERT INTO accountInventory (accountId, itemId, count) SELECT accounts.id, 5, ? FROM accounts WHERE accounts.name = ? ON DUPLICATE KEY UPDATE count=count + VALUES(count);"; + + public TempRepository(JavaPlugin plugin) + { + super(DBPool.getAccount()); + } + + public void addGemBooster(String name, int amount) + { + executeUpdate(INSERT_CLIENT_INVENTORY, new ColumnInt("count", amount), new ColumnVarChar("name", 100, name)); + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/PurchaseManager.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/PurchaseManager.java new file mode 100644 index 00000000..8f52c28a --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/PurchaseManager.java @@ -0,0 +1,75 @@ +package mineplex.enjinTranslator.purchase; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.NautHashMap; +import mineplex.serverdata.database.ResultSetCallable; +import mineplex.enjinTranslator.purchase.data.PurchaseRepository; +import mineplex.enjinTranslator.purchase.data.Package; + +public class PurchaseManager extends MiniPlugin +{ + private static Object _purchaseLock = new Object(); + + private PurchaseRepository _repository; + private NautHashMap _purchases = new NautHashMap(); + + public PurchaseManager(JavaPlugin plugin) + { + super("Purchase Manager", plugin); + + _repository = new PurchaseRepository(plugin); + + Bukkit.getServer().getScheduler().runTaskLaterAsynchronously(getPlugin(), new Runnable() + { + public void run() + { + updatePackages(); + } + }, 20L); + } + + private void updatePackages() + { + List packages = _repository.retrievePackages(); + + synchronized (_purchaseLock) + { + for (mineplex.enjinTranslator.purchase.data.Package purchasePackage : packages) + { + _purchases.put(purchasePackage.getName(), purchasePackage); + } + } + } + + public void addAccountPurchaseToQueue(int accountId, final String packageName, int count, boolean success) + { + synchronized (_purchaseLock) + { + if (!_purchases.containsKey(packageName)) + { + _repository.addPackage(packageName, new ResultSetCallable() + { + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + int packageId = resultSet.getInt(1); + + _purchases.put(packageName, new Package(packageId, packageName)); + System.out.println("Added new package : " + packageName); + } + } + }); + } + + _repository.addAccountPurchase(accountId, _purchases.get(packageName).getId(), count, success); + } + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/data/Package.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/data/Package.java new file mode 100644 index 00000000..9796b8a5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/data/Package.java @@ -0,0 +1,23 @@ +package mineplex.enjinTranslator.purchase.data; + +public class Package +{ + private int _id; + private String _name; + + public Package(int id, String name) + { + _id = id; + _name = name; + } + + public int getId() + { + return _id; + } + + public String getName() + { + return _name; + } +} diff --git a/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/data/PurchaseRepository.java b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/data/PurchaseRepository.java new file mode 100644 index 00000000..ba90e480 --- /dev/null +++ b/Plugins[Modified]/Mineplex.EnjinTranslator/src/mineplex/enjinTranslator/purchase/data/PurchaseRepository.java @@ -0,0 +1,57 @@ +package mineplex.enjinTranslator.purchase.data; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import mineplex.core.database.MinecraftRepository; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.ResultSetCallable; +import mineplex.serverdata.database.column.ColumnBoolean; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class PurchaseRepository extends RepositoryBase +{ + private static String INSERT_ACCOUNT_PURCHASE = "INSERT INTO accountPurchases (accountId, packageId, amount, date, success) VALUES (?, ?, ?, now(), ?);"; + + private static String INSERT_PACKAGE = "INSERT INTO packages (packageName) VALUES (?);"; + private static String RETRIEVE_PACKAGES = "SELECT id, packageName FROM packages;"; + + public PurchaseRepository(JavaPlugin plugin) + { + super(DBPool.getAccount()); + } + + public void addPackage(String name, ResultSetCallable callable) + { + executeInsert(INSERT_PACKAGE, callable, new ColumnVarChar("packageName", 100, name)); + } + + public List retrievePackages() + { + final List packages = new ArrayList(); + + executeQuery(RETRIEVE_PACKAGES, new ResultSetCallable() + { + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + packages.add(new Package(resultSet.getInt(1), resultSet.getString(2))); + } + } + }); + + return packages; + } + + public boolean addAccountPurchase(int accountId, int packageId, int count, boolean success) + { + return executeInsert(INSERT_ACCOUNT_PURCHASE, null, new ColumnInt("accountId", accountId), new ColumnInt("packageId", packageId), new ColumnInt("count", count), new ColumnBoolean("success", success)) > 0; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Compensation/plugin.yml b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/plugin.yml new file mode 100644 index 00000000..1ee7068c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/plugin.yml @@ -0,0 +1,4 @@ +name: Compensation +main: mineplex.game.clans.compensation.ClansCompensation +version: 1.0 +depend: [Clans] \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Compensation/pom.xml b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/pom.xml new file mode 100644 index 00000000..008bc998 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + ClansCompensation + mineplex-game-clans-compensation + + + + ${project.groupId} + mineplex-game-clans + ${project.version} + provided + + + diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Compensation/src/mineplex/game/clans/compensation/ClansCompensation.java b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/src/mineplex/game/clans/compensation/ClansCompensation.java new file mode 100644 index 00000000..2a180e79 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/src/mineplex/game/clans/compensation/ClansCompensation.java @@ -0,0 +1,785 @@ +package mineplex.game.clans.compensation; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.UUID; + +import org.apache.commons.io.FileUtils; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.amplifiers.AmplifierManager.AmplifierType; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.items.ItemType; +import mineplex.game.clans.items.RareItemFactory; +import mineplex.game.clans.items.attributes.armor.ConqueringArmorAttribute; +import mineplex.game.clans.items.attributes.armor.PaddedAttribute; +import mineplex.game.clans.items.attributes.armor.ReinforcedAttribute; +import mineplex.game.clans.items.attributes.armor.SlantedAttribute; +import mineplex.game.clans.items.attributes.bow.HeavyArrowsAttribute; +import mineplex.game.clans.items.attributes.bow.HuntingAttribute; +import mineplex.game.clans.items.attributes.bow.InverseAttribute; +import mineplex.game.clans.items.attributes.bow.LeechingAttribute; +import mineplex.game.clans.items.attributes.bow.RecursiveAttribute; +import mineplex.game.clans.items.attributes.bow.ScorchingAttribute; +import mineplex.game.clans.items.attributes.bow.SlayingAttribute; +import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute; +import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; +import mineplex.game.clans.items.attributes.weapon.FrostedAttribute; +import mineplex.game.clans.items.attributes.weapon.HasteAttribute; +import mineplex.game.clans.items.attributes.weapon.JaggedAttribute; +import mineplex.game.clans.items.attributes.weapon.SharpAttribute; +import mineplex.game.clans.items.economy.GoldToken; +import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.GiantsBroadsword; +import mineplex.game.clans.items.legendaries.HyperAxe; +import mineplex.game.clans.items.legendaries.MagneticMaul; +import mineplex.game.clans.items.legendaries.MeridianScepter; +import mineplex.game.clans.items.legendaries.WindBlade; + +public class ClansCompensation extends JavaPlugin implements Listener +{ + public enum Perm implements Permission + { + COMPENSATION_COMMAND, + } + + private final List _compensating = new ArrayList<>(); + private boolean _debug; + + @Override + public void onEnable() + { + System.out.println("[INFO] Enabling ClansCompensation"); + Bukkit.getPluginManager().registerEvents(this, this); + PermissionGroup.PLAYER.setPermission(Perm.COMPENSATION_COMMAND, true, true); + ClansManager.getInstance().addCommand(new CompensationCommand(ClansManager.getInstance(), this)); + loadUUIDs(uuids -> + { + _compensating.clear(); + _compensating.addAll(uuids); + }); + try + { + _debug = new File(new File(".").getCanonicalPath() + File.separator + "DebugCompensation.dat").exists(); + } + catch (IOException e) + { + _debug = false; + } + } + + @Override + public void onDisable() + { + System.out.println("[INFO] Disabling ClansCompensation"); + saveUUIDs(false); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + if (canClaim(event.getPlayer().getUniqueId())) + { + UtilPlayer.message(event.getPlayer(), F.main("Compensation", "You have a compensation package ready to open! Run /compensation to get started!")); + } + } + + public boolean canClaim(UUID uuid) + { + if (_debug) + { + return true; + } + return _compensating.contains(uuid); + } + + public void claim(Player player) + { + if (_debug || _compensating.remove(player.getUniqueId())) + { + Block[] possible = new Block[] + { + player.getLocation().getBlock().getRelative(1, 0, 0), + player.getLocation().getBlock().getRelative(-1, 0, 0), + player.getLocation().getBlock().getRelative(0, 0, 1), + player.getLocation().getBlock().getRelative(0, 0, -1) + }; + + Block spawn = null; + Block spawn2 = null; + for (Block block : possible) + { + if (spawn != null && spawn2 != null) + { + break; + } + ClanTerritory claim = ClansManager.getInstance().getClanUtility().getClaim(block.getLocation()); + if (claim != null) + { + if (ClansManager.getInstance().getClan(player) == null) + { + continue; + } + ClanInfo clan = ClansManager.getInstance().getClan(player); + if (!clan.getName().equals(claim.Owner)) + { + continue; + } + } + ClansManager.getInstance().getBlockRestore().restore(block); + if (block.getType() != Material.AIR) + { + continue; + } + boolean overlap = false; + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + Block check = block.getRelative(x, 0, z); + if (check.getType() == Material.CHEST) + { + overlap = true; + } + } + } + if (overlap) + { + continue; + } + + if (spawn == null) + { + spawn = block; + continue; + } + if (spawn2 == null) + { + spawn2 = block; + continue; + } + } + + if (spawn == null || spawn2 == null) + { + UtilPlayer.message(player, F.main("Compensation", "Try that again in a different spot!")); + if (!_debug) + { + _compensating.add(player.getUniqueId()); + } + return; + } + else + { + spawn.setType(Material.CHEST); + spawn2.setType(Material.CHEST); + Chest one = (Chest)spawn.getState(); + Chest two = (Chest)spawn2.getState(); + FireworkEffect effect = FireworkEffect.builder().with(FireworkEffect.Type.BALL).withColor(Color.MAROON).withFade(Color.NAVY).withFlicker().build(); + UtilFirework.playFirework(spawn.getLocation().add(0.5, 0.5, 0.5), effect); + UtilFirework.playFirework(spawn2.getLocation().add(0.5, 0.5, 0.5), effect); + + List items = new ArrayList<>(); + { + UtilPlayer.message(player, F.main("Compensation", "You received two " + F.name(AmplifierType.SIXTY.getDisplayName() + "s") + "!")); + ClansManager.getInstance().getInventoryManager().addItemToInventory(player, AmplifierType.SIXTY.getFullItemName(), 2); + for (int i = 0; i < 10; i++) + { + items.add(new GoldToken(50000).toItemStack()); + } + items.add(ItemStackFactory.Instance.CreateStack(Material.BEACON, (byte) 0, 1, C.cGold + "Supply Drop")); + items.add(new ItemStack(Material.DIAMOND_HELMET, 5)); + items.add(new ItemStack(Material.DIAMOND_CHESTPLATE, 5)); + items.add(new ItemStack(Material.DIAMOND_LEGGINGS, 5)); + items.add(new ItemStack(Material.DIAMOND_BOOTS, 5)); + items.add(new ItemStack(Material.IRON_HELMET, 5)); + items.add(new ItemStack(Material.IRON_CHESTPLATE, 5)); + items.add(new ItemStack(Material.IRON_LEGGINGS, 5)); + items.add(new ItemStack(Material.IRON_BOOTS, 5)); + items.add(new ItemStack(Material.GOLD_HELMET, 5)); + items.add(new ItemStack(Material.GOLD_CHESTPLATE, 5)); + items.add(new ItemStack(Material.GOLD_LEGGINGS, 5)); + items.add(new ItemStack(Material.GOLD_BOOTS, 5)); + items.add(new ItemStack(Material.CHAINMAIL_HELMET, 5)); + items.add(new ItemStack(Material.CHAINMAIL_CHESTPLATE, 5)); + items.add(new ItemStack(Material.CHAINMAIL_LEGGINGS, 5)); + items.add(new ItemStack(Material.CHAINMAIL_BOOTS, 5)); + items.add(new ItemStack(Material.LEATHER_HELMET, 5)); + items.add(new ItemStack(Material.LEATHER_CHESTPLATE, 5)); + items.add(new ItemStack(Material.LEATHER_LEGGINGS, 5)); + items.add(new ItemStack(Material.LEATHER_BOOTS, 5)); + items.add(new ItemStack(Material.DIAMOND_SWORD, 5)); + items.add(new ItemStack(Material.DIAMOND_AXE, 5)); + items.add(new ItemStack(Material.GOLD_SWORD, 5)); + items.add(new ItemStack(Material.GOLD_AXE, 5)); + items.add(new ItemStack(Material.IRON_SWORD, 5)); + items.add(new ItemStack(Material.IRON_AXE, 5)); + items.add(new ItemStack(Material.BOW, 5)); + items.add(new ItemBuilder(Material.ENCHANTMENT_TABLE).setTitle(C.cGreenB + "Class Shop").build()); + items.add(new ItemStack(Material.ANVIL, 3)); + Random rand = new Random(); + for (int i = 0; i < 3; i++) + { + int picked = rand.nextInt(24 * 3); + RareItemFactory factory; + switch (picked) + { + case 0: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(WindBlade.class); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 1: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setSuperPrefix(FrostedAttribute.class); + items.add(factory.fabricate()); + break; + case 2: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_SWORD); + factory.setSuperPrefix(FlamingAttribute.class); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 3: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(AlligatorsTooth.class); + items.add(factory.fabricate()); + break; + case 4: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setSuperPrefix(LeechingAttribute.class); + items.add(factory.fabricate()); + break; + case 5: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setPrefix(JaggedAttribute.class); + factory.setSuffix(ConqueringAttribute.class); + items.add(factory.fabricate()); + break; + case 6: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(GiantsBroadsword.class); + items.add(factory.fabricate()); + break; + case 7: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 8: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 9: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(MagneticMaul.class); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 10: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.GOLD_SWORD); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 11: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 12: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(MeridianScepter.class); + items.add(factory.fabricate()); + break; + case 13: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setPrefix(JaggedAttribute.class); + factory.setSuffix(ConqueringAttribute.class); + items.add(factory.fabricate()); + break; + case 14: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_SWORD); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 15: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(AlligatorsTooth.class); + items.add(factory.fabricate()); + break; + case 16: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuperPrefix(FrostedAttribute.class); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 17: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.GOLD_AXE); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 18: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(WindBlade.class); + factory.setSuffix(ConqueringAttribute.class); + items.add(factory.fabricate()); + break; + case 19: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_SWORD); + factory.setSuperPrefix(FrostedAttribute.class); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 20: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setSuperPrefix(FrostedAttribute.class); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 21: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(GiantsBroadsword.class); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 22: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuffix(ConqueringAttribute.class); + items.add(factory.fabricate()); + break; + case 23: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setPrefix(RecursiveAttribute.class); + items.add(factory.fabricate()); + break; + case 24: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(HyperAxe.class); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 25: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setPrefix(HeavyArrowsAttribute.class); + items.add(factory.fabricate()); + break; + case 26: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.GOLD_SWORD); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 27: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(MeridianScepter.class); + items.add(factory.fabricate()); + break; + case 28: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.GOLD_SWORD); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 29: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 30: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(WindBlade.class); + items.add(factory.fabricate()); + break; + case 31: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setSuperPrefix(ScorchingAttribute.class); + factory.setSuffix(SlayingAttribute.class); + items.add(factory.fabricate()); + break; + case 32: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 33: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(HyperAxe.class); + items.add(factory.fabricate()); + break; + case 34: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_SWORD); + factory.setSuperPrefix(FlamingAttribute.class); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 35: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setSuperPrefix(FrostedAttribute.class); + items.add(factory.fabricate()); + break; + case 36: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(GiantsBroadsword.class); + items.add(factory.fabricate()); + break; + case 37: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setPrefix(InverseAttribute.class); + items.add(factory.fabricate()); + break; + case 38: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.DIAMOND_CHESTPLATE); + factory.setPrefix(ReinforcedAttribute.class); + items.add(factory.fabricate()); + break; + case 39: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(WindBlade.class); + items.add(factory.fabricate()); + break; + case 40: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.LEATHER_BOOTS); + factory.setPrefix(SlantedAttribute.class); + items.add(factory.fabricate()); + break; + case 41: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_SWORD); + factory.setSuperPrefix(FrostedAttribute.class); + items.add(factory.fabricate()); + break; + case 42: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(GiantsBroadsword.class); + items.add(factory.fabricate()); + break; + case 43: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.IRON_LEGGINGS); + factory.setPrefix(PaddedAttribute.class); + items.add(factory.fabricate()); + break; + case 44: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.GOLD_SWORD); + factory.setPrefix(SharpAttribute.class); + items.add(factory.fabricate()); + break; + case 45: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(MeridianScepter.class); + items.add(factory.fabricate()); + break; + case 46: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.CHAINMAIL_CHESTPLATE); + factory.setPrefix(SlantedAttribute.class); + items.add(factory.fabricate()); + break; + case 47: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_SWORD); + factory.setSuffix(ConqueringAttribute.class); + items.add(factory.fabricate()); + break; + case 48: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(MagneticMaul.class); + factory.setPrefix(SharpAttribute.class); + items.add(factory.fabricate()); + break; + case 49: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.IRON_HELMET); + factory.setSuffix(ConqueringArmorAttribute.class); + items.add(factory.fabricate()); + break; + case 50: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuffix(HasteAttribute.class); + items.add(factory.fabricate()); + break; + case 51: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(AlligatorsTooth.class); + factory.setSuperPrefix(FrostedAttribute.class); + items.add(factory.fabricate()); + break; + case 52: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.LEATHER_BOOTS); + factory.setPrefix(ReinforcedAttribute.class); + items.add(factory.fabricate()); + break; + case 53: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.IRON_LEGGINGS); + factory.setPrefix(SlantedAttribute.class); + items.add(factory.fabricate()); + break; + case 54: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(HyperAxe.class); + items.add(factory.fabricate()); + break; + case 55: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setPrefix(RecursiveAttribute.class); + items.add(factory.fabricate()); + break; + case 56: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.CHAINMAIL_BOOTS); + factory.setPrefix(PaddedAttribute.class); + items.add(factory.fabricate()); + break; + case 57: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(GiantsBroadsword.class); + factory.setSuffix(ConqueringAttribute.class); + items.add(factory.fabricate()); + break; + case 58: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.IRON_HELMET); + factory.setPrefix(SlantedAttribute.class); + factory.setSuffix(ConqueringArmorAttribute.class); + items.add(factory.fabricate()); + break; + case 59: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setPrefix(InverseAttribute.class); + items.add(factory.fabricate()); + break; + case 60: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(WindBlade.class); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 61: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_AXE); + factory.setSuperPrefix(FrostedAttribute.class); + items.add(factory.fabricate()); + break; + case 62: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.LEATHER_BOOTS); + factory.setPrefix(PaddedAttribute.class); + items.add(factory.fabricate()); + break; + case 63: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(AlligatorsTooth.class); + items.add(factory.fabricate()); + break; + case 64: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.GOLD_AXE); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 65: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.DIAMOND_SWORD); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 66: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(MeridianScepter.class); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + case 67: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_AXE); + factory.setSuperPrefix(FrostedAttribute.class); + items.add(factory.fabricate()); + break; + case 68: + factory = new RareItemFactory(ItemType.BOW); + factory.setType(Material.BOW); + factory.setPrefix(HuntingAttribute.class); + items.add(factory.fabricate()); + break; + case 69: + factory = new RareItemFactory(ItemType.LEGENDARY); + factory.setLegendary(HyperAxe.class); + factory.setPrefix(JaggedAttribute.class); + items.add(factory.fabricate()); + break; + case 70: + factory = new RareItemFactory(ItemType.ARMOR); + factory.setType(Material.DIAMOND_CHESTPLATE); + factory.setPrefix(ReinforcedAttribute.class); + items.add(factory.fabricate()); + break; + case 71: + factory = new RareItemFactory(ItemType.WEAPON); + factory.setType(Material.IRON_AXE); + factory.setSuperPrefix(FlamingAttribute.class); + items.add(factory.fabricate()); + break; + } + } + for (int slot = 0; slot < one.getBlockInventory().getSize(); slot++) + { + if (items.isEmpty()) + { + break; + } + one.getBlockInventory().setItem(slot, items.remove(0)); + } + for (int slot = 0; slot < two.getBlockInventory().getSize(); slot++) + { + if (items.isEmpty()) + { + break; + } + two.getBlockInventory().setItem(slot, items.remove(0)); + } + } + } + } + } + + private void loadUUIDs(Callback> uuidCallback) + { + ClansManager.getInstance().runAsync(() -> + { + List ret = new ArrayList<>(); + try + { + FileInputStream fstream = new FileInputStream(new File(".").getCanonicalPath() + File.separator + "compensating.dat"); + DataInputStream in = new DataInputStream(fstream); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String line = null; + while ((line = br.readLine()) != null) + { + UUID uuid = UUID.fromString(line); + ret.add(uuid); + } + br.close(); + in.close(); + fstream.close(); + + uuidCallback.run(ret); + } + catch (Exception e) + { + e.printStackTrace(); + uuidCallback.run(ret); + } + }); + } + + private void saveUUIDs(boolean async) + { + Runnable r = () -> + { + try + { + File storage = new File(new File(".").getCanonicalPath() + File.separator + "compensating.dat"); + if (storage.exists()) + { + FileUtils.deleteQuietly(storage); + } + + if (!_compensating.isEmpty()) + { + storage.createNewFile(); + + FileWriter fstream = new FileWriter(storage); + BufferedWriter out = new BufferedWriter(fstream); + + out.write(_compensating.get(0).toString()); + + for (int i = 1; i < _compensating.size(); i++) + { + UUID comp = _compensating.get(i); + out.write("\n"); + out.write(comp.toString()); + } + out.close(); + fstream.close(); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + }; + + if (async) + { + ClansManager.getInstance().runAsync(r); + } + else + { + r.run(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Compensation/src/mineplex/game/clans/compensation/CompensationCommand.java b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/src/mineplex/game/clans/compensation/CompensationCommand.java new file mode 100644 index 00000000..831f24af --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Compensation/src/mineplex/game/clans/compensation/CompensationCommand.java @@ -0,0 +1,64 @@ +package mineplex.game.clans.compensation; + +import java.util.Random; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; + +public class CompensationCommand extends CommandBase +{ + private final ClansCompensation _main; + private final String _secretKey; + + public CompensationCommand(ClansManager plugin, ClansCompensation main) + { + super(plugin, ClansCompensation.Perm.COMPENSATION_COMMAND, "compensation"); + + _main = main; + char[] characters = "abcdefghijklmnopqrstuvwxyz".toCharArray(); + StringBuilder keyBuilder = new StringBuilder(); + Random rand = new Random(); + while (keyBuilder.length() < 10) + { + keyBuilder.append(characters[rand.nextInt(characters.length)]); + } + _secretKey = keyBuilder.toString(); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (_main.canClaim(caller.getUniqueId())) + { + if (args.length >= 1 && args[0].equals(_secretKey)) + { + _main.claim(caller); + } + else + { + TextComponent message = new TextComponent("Confirm"); + message.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/compensation " + _secretKey)); + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Redeem your items").create())); + message.setColor(ChatColor.GREEN); + message.setBold(true); + caller.sendMessage(C.cRedB + "WARNING: " + C.cGray + "You are about to claim several free items. Other players may attempt to steal these items from you, so it is highly recommended that you only run this command inside of your own base. Are you sure you wish to claim your items at this time?"); + caller.spigot().sendMessage(message); + } + } + else + { + UtilPlayer.message(caller, F.main("Compensation", "You do not have a compensation package!")); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/pom.xml b/Plugins[Modified]/Mineplex.Game.Clans.Core/pom.xml new file mode 100644 index 00000000..8a51dd13 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + + com.mineplex + mineplex-parent + dev-SNAPSHOT + + + mineplex-game-clans-core + + + + ${project.groupId} + mineplex-core + ${project.version} + + + diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClaimLocation.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClaimLocation.java new file mode 100644 index 00000000..ec3fb85e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClaimLocation.java @@ -0,0 +1,65 @@ +package mineplex.game.clans.core; + +import java.util.Objects; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; + +public class ClaimLocation +{ + public final String _worldName; + public final int _chunkX; + public final int _chunkZ; + + private ClaimLocation(String worldName, int chunkX, int chunkZ) + { + _worldName = worldName; + _chunkX = chunkX; + _chunkZ = chunkZ; + } + + public static ClaimLocation of(String worldName, int chunkX, int chunkZ) + { + return new ClaimLocation(worldName, chunkX, chunkZ); + } + + public static ClaimLocation of(Chunk chunk) + { + return new ClaimLocation(chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); + } + + public static ClaimLocation fromStoredString(String storedFormat) // TODO: change stored format for next season + { + // Current format: world,x,z + String[] split = storedFormat.split(","); + return new ClaimLocation(split[0], Integer.parseInt(split[1]), Integer.parseInt(split[2])); + } + + public String toStoredString() // TODO: change stored format for next season + { + return _worldName + "," + _chunkX + "," + _chunkZ; + } + + public Chunk toChunk() + { + return Bukkit.getWorld(_worldName).getChunkAt(_chunkX, _chunkZ); + } + + @Override + public int hashCode() + { + return Objects.hash(_worldName, _chunkX, _chunkZ); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof ClaimLocation)) + { + return false; + } + + ClaimLocation that = (ClaimLocation) other; + return Objects.equals(_worldName, that._worldName) && Objects.equals(_chunkX, that._chunkX) && Objects.equals(_chunkZ, that._chunkZ); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClanDeleteCommand.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClanDeleteCommand.java new file mode 100644 index 00000000..ed982367 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClanDeleteCommand.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.core; + +import mineplex.game.clans.core.repository.tokens.SimpleClanToken; +import mineplex.serverdata.commands.ServerCommand; + + +public class ClanDeleteCommand extends ServerCommand +{ + private String _clanName; + public String getClanName() { return _clanName; } + + public ClanDeleteCommand(String serverName, String clanName) + { + super(serverName); + + _clanName = clanName; + } + + public ClanDeleteCommand(SimpleClanToken clan) + { + this(clan.getHomeServer(), clan.getClanName()); + } + + @Override + public void run() + { + // Utilitizes a callback functionality to seperate dependencies + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClanLoadCommand.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClanLoadCommand.java new file mode 100644 index 00000000..b0d28e6b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/ClanLoadCommand.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.core; + +import mineplex.serverdata.commands.ServerCommand; + + +public class ClanLoadCommand extends ServerCommand +{ + private String _clanName; + public String getClanName() { return _clanName; } + + public ClanLoadCommand(String serverName, String clanName) + { + super(serverName); + + _clanName = clanName; + } + + @Override + public void run() + { + // Utilitizes a callback functionality to seperate dependencies + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/ClanRepository.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/ClanRepository.java new file mode 100644 index 00000000..b57b279c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/ClanRepository.java @@ -0,0 +1,582 @@ +package mineplex.game.clans.core.repository; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; +import org.jooq.DSLContext; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.NautHashMap; +import mineplex.database.tables.records.ClansRecord; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.tokens.ClanAllianceToken; +import mineplex.game.clans.core.repository.tokens.ClanMemberToken; +import mineplex.game.clans.core.repository.tokens.ClanTerritoryToken; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.core.repository.tokens.ClanWarToken; +import mineplex.game.clans.core.repository.tokens.SimpleClanToken; +import mineplex.game.clans.core.war.ClanWarData; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.ResultSetCallable; +import mineplex.serverdata.database.column.Column; +import mineplex.serverdata.database.column.ColumnBoolean; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnTimestamp; +import mineplex.serverdata.database.column.ColumnVarChar; + +import static mineplex.database.Tables.accountClan; +import static mineplex.database.Tables.accounts; +import static mineplex.database.Tables.clans; +import static org.jooq.impl.DSL.select; + +public class ClanRepository extends RepositoryBase +{ + private static String CREATE_CLAN_TABLE = "CREATE TABLE IF NOT EXISTS clans (id INT NOT NULL AUTO_INCREMENT, serverId INT NOT NULL, name VARCHAR(100), description VARCHAR(140), home VARCHAR(140), admin BIT(1), dateCreated DATETIME, lastOnline DATETIME, energy INT, PRIMARY KEY (id), INDEX clanName (name));"; + private static String CREATE_ACCOUNT_CLAN_TABLE = "CREATE TABLE IF NOT EXISTS accountClan (id INT NOT NULL AUTO_INCREMENT, accountId INT, clanId INT, clanRole VARCHAR(140), PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts(id), FOREIGN KEY (clanId) REFERENCES clans(id), INDEX clanIdIndex (clanId));"; + private static String CREATE_CLAN_TERRITORY_TABLE = "CREATE TABLE IF NOT EXISTS clanTerritory (id INT NOT NULL AUTO_INCREMENT, clanId INT, chunk VARCHAR(100), safe BIT(1), PRIMARY KEY (id), FOREIGN KEY (clanId) REFERENCES clans(id));"; + private static String CREATE_CLAN_ALLIANCE_TABLE = "CREATE TABLE IF NOT EXISTS clanAlliances (id INT NOT NULL AUTO_INCREMENT, clanId INT, otherClanId INT, trusted BIT(1), PRIMARY KEY (id), FOREIGN KEY (otherClanId) REFERENCES clans(id), FOREIGN KEY (clanId) REFERENCES clans(id), INDEX clanIdIndex (clanId));"; + + private static String RETRIEVE_CLAN_INFO = "SELECT c.id, c.name, c.description, c.home, c.admin, c.energy, c.kills, c.murder, c.deaths, c.warWins, c.warLosses, c.generator, c.generatorStock, c.dateCreated, c.lastOnline, c.eloRating FROM clans AS c WHERE lower(c.name) = ?;"; + private static String RETRIEVE_PLAYER_CLAN_INFO = "SELECT clans.name, accountClan.clanRole, clanServer.serverName, clans.id FROM accountClan INNER JOIN clans ON clans.id = accountClan.clanId INNER JOIN clanServer ON clans.serverId = clanServer.id WHERE accountClan.accountId = ?;"; + private static String RETRIEVE_START_CLAN_INFO = "SELECT c.id, c.name, c.description, c.home, c.admin, c.energy, c.kills, c.murder, c.deaths, c.warWins, c.warLosses, c.generator, c.generatorStock, c.dateCreated, c.lastOnline, c.eloRating, ct.chunk, ct.safe FROM clans AS c LEFT JOIN clanTerritory AS ct ON ct.clanId = c.id WHERE c.serverId = ? OR c.admin = 1;"; + private static String RETRIEVE_CLAN_MEMBER_INFO = "SELECT c.name, a.name, a.uuid, clanRole FROM accountClan AS ac INNER JOIN accounts AS a ON a.id = ac.accountId INNER JOIN clans AS c on c.id = ac.clanId WHERE c.serverId = ?;"; + private static String RETRIEVE_CLAN_MEMBERS = "SELECT c.name, a.name, a.uuid, clanRole FROM accountClan AS ac INNER JOIN accounts AS a ON a.id = ac.accountId INNER JOIN clans AS c on c.id = ac.clanId WHERE lower(c.name) = ?;"; + private static String RETRIEVE_CLAN_ALLIANCE_INFO = "SELECT c.name, cOther.name, ca.trusted FROM clanAlliances AS ca INNER JOIN clans AS c ON c.id = ca.clanId INNER JOIN clans as cOther ON cOther.id = ca.otherClanId WHERE c.serverId = ?;"; +// private static String RETRIEVE_CLAN_ENEMY_INFO = "SELECT c.name, cOther.name, clanScore, otherClanScore, clanKills, otherClanKills, timeFormed FROM clanEnemies AS ce INNER JOIN clans AS c ON c.id = ce.clanId INNER JOIN clans as cOther ON cOther.id = ce.otherClanId WHERE c.serverId = ?;"; + private static String RETRIEVE_CLAN_WAR_INFO = "SELECT c.name, cOther.name, cw.score, cw.created, cw.ended, cw.lastUpdated FROM clanWar AS cw INNER JOIN clans AS c on c.id = cw.initiatorId INNER JOIN clans as cOther ON cOther.id = cw.clanId WHERE c.serverId = ? AND completed = FALSE"; + private static String RETRIEVE_CLAN_WAR_FROM_CLAN_IDS = "SELECT c.name, cOther.name, cw.score, cw.created, cw.ended, cw.lastUpdated FROM clanWar AS cw INNER JOIN clans AS c on c.id = cw.initiatorId INNER JOIN clans as cOther ON cOther.id = cw.clanId WHERE cw.initiatorId = ? AND cw.clanId = ? AND completed = FALSE"; + + private static String DELETE_CLAN_MEMBER = "DELETE aC FROM accountClan AS aC INNER JOIN accounts ON accounts.id = aC.accountId WHERE aC.clanId = ? AND accounts.name = ?;"; + private static String DELETE_CLAN_MEMBERS = "DELETE FROM accountClan WHERE clanId = ?;"; + private static String DELETE_CLAN_TERRITORY = "DELETE FROM clanTerritory WHERE clanId = ? AND chunk = ?;"; + private static String DELETE_CLAN_ALL_TERRITORY = "DELETE FROM clanTerritory WHERE clanId = ?;"; // + private static String DELETE_CLAN_TERRITORIES = "DELETE FROM clanTerritory WHERE clanId = ?;"; // + private static String DELETE_CLAN_ALLIANCE = "DELETE FROM clanAlliances WHERE clanId = ? AND otherClanId = ?;"; + private static String DELETE_CLAN_ALLIANCES = "DELETE FROM clanAlliances WHERE clanId = ? OR otherClanId = ?;"; +// private static String DELETE_CLAN_ENEMIES = "DELETE FROM clanEnemies WHERE clanId = ? OR otherClanId = ?;"; + private static String DELETE_CLAN = "DELETE FROM clans WHERE id = ?;"; + private static String DELETE_ALL_WAR = "DELETE FROM clanWar WHERE initiatorId = ? OR clanId = ?"; + + private static String ADD_CLAN = "INSERT INTO clans (serverId, name, description, home, admin, dateCreated, energy, lastOnline) VALUES (?, ?, ?, ?, ?, now(), ?, now());"; + private static String ADD_CLAN_MEMBER = "INSERT INTO accountClan (accountId, clanId, clanRole) SELECT accounts.id, ?, ? FROM accounts WHERE accounts.name = ?;"; + private static String ADD_CLAN_ALLIANCE = "INSERT INTO clanAlliances (clanId, otherClanId, trusted) VALUES (?, ?, ?);"; + private static String ADD_CLAN_WAR = "INSERT INTO clanWar (initiatorId, clanId, score, created, lastUpdated) VALUES (?, ?, ?, ?, ?)"; + private static String ADD_CLAN_TERRITORY = "INSERT INTO clanTerritory (clanId, chunk, safe) VALUES (?, ?, ?);"; + + //Not Sure if UPDATE_CLAN should set eloRating, but I would think it would need to + private static String UPDATE_CLAN = "UPDATE clans SET name = ?, description = ?, home = ?, admin = ?, energy = ?, kills = ?, murder = ?, deaths = ?, warWins = ?, warLosses = ?, lastOnline = ? WHERE id = ?;"; + private static String UPDATE_CLAN_MEMBER = "UPDATE accountClan AS AC INNER JOIN accounts ON accounts.id = AC.accountId SET AC.clanRole = ? WHERE AC.clanId = ? AND accounts.name = ?;"; + private static String UPDATE_CLAN_ALLIANCE = "UPDATE clanAlliances SET trusted = ? WHERE clanId = ? AND otherClanId = ?;"; + private static String UPDATE_CLAN_TERRITORY = "UPDATE clanTerritory SET safe = ? WHERE chunk = ?;"; // + private static String UPDATE_CLAN_WAR = "UPDATE clanWar SET score = ?, lastUpdated = ? WHERE initiatorId = ? AND clanId = ?"; + private static String UPDATE_CLAN_SERVER_ID = "UPDATE clans SET serverId = ?, home = '', generator = '' WHERE id = ?;"; + private static String UPDATE_CLAN_GENERATOR = "UPDATE clans SET generator = ?, generatorStock = ? WHERE id = ?;"; + + private static String GET_CLAN_SERVER = "SELECT id FROM clanServer WHERE clanServer.serverName = ?"; + private static String ADD_CLAN_SERVER = "INSERT INTO clanServer (serverName) VALUES (?);"; + + private String _serverName; + private int _serverId; + + public ClanRepository(JavaPlugin plugin, String serverName, boolean isClansServer) + { + super(DBPool.getAccount()); + + _serverName = serverName; + _serverId = -1; + + if (isClansServer) + { + loadServerId(); + } + } + + public ClanRepository(JavaPlugin plugin, String serverName) + { + this(plugin, serverName, false); + } + + private void loadServerId() + { + ResultSetCallable callable = new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + _serverId = resultSet.getInt(1); + } + } + }; + + executeQuery(GET_CLAN_SERVER, callable, new ColumnVarChar("serverName", 100, _serverName)); + + if (_serverId == -1) + { + // Need to insert server into database + executeInsert(ADD_CLAN_SERVER, callable, new ColumnVarChar("serverName", 100, _serverName)); + + if (_serverId == -1) + { + System.out.println("Error loading serverId from database. Shutting down server!"); + Bukkit.shutdown(); + return; + } + } + + System.out.println("Loaded Server ID: " + _serverId); + } + + @Override + protected void initialize() + { + executeUpdate(CREATE_CLAN_TABLE); + executeUpdate(CREATE_ACCOUNT_CLAN_TABLE); + executeUpdate(CREATE_CLAN_TERRITORY_TABLE); + executeUpdate(CREATE_CLAN_ALLIANCE_TABLE); + } + + /** + * Updates a clan's home server while removing all + * alliances, enemies, teritory claims and homes set on + * originating server. + * @param clanId - the id of the clan to move + */ + public void moveClanServer(final int clanId, String serverName, final Callback callback) + { + executeQuery(GET_CLAN_SERVER, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + boolean success = resultSet.next(); + + if (success) + { + int serverId = resultSet.getInt(1); + ColumnInt clanIdCol = new ColumnInt("clanId", clanId); + ColumnInt serverIdCol = new ColumnInt("serverId", serverId); + + executeUpdate(DELETE_CLAN_ALLIANCES, clanIdCol, clanIdCol); + deleteAllWar(clanId); + executeUpdate(DELETE_CLAN_TERRITORIES, clanIdCol); + executeUpdate(UPDATE_CLAN_SERVER_ID, serverIdCol, clanIdCol); + } + + callback.run(success); + } + }, new ColumnVarChar("serverName", 100, serverName)); + + } + + public ClanToken retrieveClan(String clanName) + { + final ClanToken clan = new ClanToken(); + + executeQuery(RETRIEVE_CLAN_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + if (resultSet.next()) + { + clan.Id = resultSet.getInt(1); + clan.Name = resultSet.getString(2); + clan.Description = resultSet.getString(3); + clan.Home = resultSet.getString(4); + clan.Admin = resultSet.getBoolean(5); + clan.Energy = resultSet.getInt(6); + clan.Kills = resultSet.getInt(7); + clan.Murder = resultSet.getInt(8); + clan.Deaths = resultSet.getInt(9); + clan.WarWins = resultSet.getInt(10); + clan.WarLosses = resultSet.getInt(11); + clan.GeneratorBuyer = resultSet.getString(12); + clan.GeneratorStock = resultSet.getInt(13); + clan.DateCreated = resultSet.getTimestamp(14); + clan.LastOnline = resultSet.getTimestamp(15); + + clan.EloRating = resultSet.getInt(16); + } + } + }, new ColumnVarChar("name", 100, clanName.toLowerCase())); + + executeQuery(RETRIEVE_CLAN_MEMBERS, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + String clanName = resultSet.getString(1); + + ClanMemberToken memberToken = new ClanMemberToken(); + memberToken.Name = resultSet.getString(2); + memberToken.PlayerUUID = UUID.fromString(resultSet.getString(3)); + memberToken.ClanRole = resultSet.getString(4); + + clan.Members.add(memberToken); + } + } + + }, new ColumnVarChar("name", 100, clanName.toLowerCase())); + + return clan; + } + + public void clanExists(String clanName, final Callback callback) + { + executeQuery(RETRIEVE_CLAN_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + boolean clanExists = resultSet.next(); + callback.run(clanExists); + } + }, new ColumnVarChar("name", 100, clanName.toLowerCase())); + } + + public void retrievePlayersClan(int accountId, final Callback callback) + { + executeQuery(RETRIEVE_PLAYER_CLAN_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + SimpleClanToken clanToken = null; + if (resultSet.next()) + { + String clanName = resultSet.getString(1); + String clanRole = resultSet.getString(2); + String homeServer = resultSet.getString(3); + int clanId = resultSet.getInt(4); + clanToken = new SimpleClanToken(clanName, clanRole, homeServer, clanId); + } + + callback.run(clanToken); + } + }, new ColumnInt("accountId", accountId)); + } + + public Collection retrieveClans() + { + System.out.println("Beginning to load clans from database..."); + final NautHashMap clans = new NautHashMap(); + + executeQuery(RETRIEVE_START_CLAN_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + ClanToken token = new ClanToken(); + token.Id = resultSet.getInt(1); + token.Name = resultSet.getString(2); + token.Description = resultSet.getString(3); + token.Home = resultSet.getString(4); + token.Admin = resultSet.getBoolean(5); + token.Energy = resultSet.getInt(6); + token.Kills = resultSet.getInt(7); + token.Murder = resultSet.getInt(8); + token.Deaths = resultSet.getInt(9); + token.WarWins = resultSet.getInt(10); + token.WarLosses = resultSet.getInt(11); + + token.GeneratorBuyer = resultSet.getString(12); + token.GeneratorStock = resultSet.getInt(13); + token.DateCreated = resultSet.getTimestamp(14); + token.LastOnline = resultSet.getTimestamp(15); + + token.EloRating = resultSet.getInt(16); + + ClanTerritoryToken territoryToken = new ClanTerritoryToken(); + territoryToken.ClanName = token.Name; + territoryToken.Chunk = resultSet.getString(17); + territoryToken.Safe = resultSet.getBoolean(18); + + if (!clans.containsKey(token.Name)) + { + clans.put(token.Name, token); + } + + if (territoryToken.Chunk != null) + clans.get(token.Name).Territories.add(territoryToken); + } + } + + }, new ColumnInt("serverId", _serverId)); + + System.out.println("1"); + + executeQuery(RETRIEVE_CLAN_MEMBER_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + String clanName = resultSet.getString(1); + + if (clans.containsKey(clanName)) + { + ClanMemberToken memberToken = new ClanMemberToken(); + memberToken.Name = resultSet.getString(2); + memberToken.PlayerUUID = UUID.fromString(resultSet.getString(3)); + memberToken.ClanRole = resultSet.getString(4); + + clans.get(clanName).Members.add(memberToken); + } + } + } + + }, new ColumnInt("serverId", _serverId)); + + System.out.println("2"); + + executeQuery(RETRIEVE_CLAN_ALLIANCE_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + String clanName = resultSet.getString(1); + + if (clans.containsKey(clanName)) + { + ClanAllianceToken allianceToken = new ClanAllianceToken(); + allianceToken.ClanName = resultSet.getString(2); + allianceToken.Trusted = resultSet.getBoolean(3); + + clans.get(clanName).Alliances.add(allianceToken); + } + } + } + + }, new ColumnInt("serverId", _serverId)); + + System.out.println("3"); + + executeQuery(RETRIEVE_CLAN_WAR_INFO, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + ClanWarToken warToken = new ClanWarToken(); + String clanA = resultSet.getString(1); + String clanB = resultSet.getString(2); + int score = resultSet.getInt(3); + Timestamp created = resultSet.getTimestamp(4); +// warToken.Ended = resultSet.getTimestamp(5); + Timestamp updated = resultSet.getTimestamp(6); + ClanWarData warData = new ClanWarData(clanA, clanB, score, created, updated, 0); + warToken.WarData = warData; + + if (clans.containsKey(warToken.WarData.getClanA()) && clans.containsKey(warToken.WarData.getClanB())) + { + System.out.println("Loaded War Token: " + warToken.WarData.getClanA()); + clans.get(warToken.WarData.getClanA()).WarsOut.add(warToken); + clans.get(warToken.WarData.getClanB()).WarsIn.add(warToken); + } + } + } + }, new ColumnInt("serverId", _serverId)); + + System.out.println("Finished loading clans from database..."); + return clans.values(); + } + + public boolean deleteClan(int clanId) + { + return jooq().delete(clans).where(clans.id.equal(clanId)).execute() == 1; + } + + public int addClan(ClanToken token) + { + ClansRecord record = jooq().newRecord(clans); + record.setServerId(_serverId); + record.setName(token.Name); + record.setDescription(token.Description); + record.setHome(token.Home); + record.setAdmin(token.Admin); + record.setEnergy(token.Energy); + + if (record.store() == 1) + { + return record.getId(); + } + else + { + return -1; + } + } + + @Deprecated + public boolean addMember(int clanId, String playerName, String role) + { + DSLContext create = jooq(); + int out = create.insertInto(accountClan) + .set(accountClan.accountId, select(accounts.id).from(accounts).where(accounts.name.eq(playerName))) + .set(accountClan.clanId, clanId) + .set(accountClan.clanRole, role).execute(); + + return out == 1; + } + + public boolean addMember(int clanId, UUID playerUUID, String role) + { + int out = jooq().insertInto(accountClan) + .set(accountClan.accountId, select(accounts.id).from(accounts).where(accounts.uuid.eq(playerUUID.toString()))) + .set(accountClan.clanId, clanId) + .set(accountClan.clanRole, role).execute(); + + return out == 1; + } + + public boolean removeMember(int clanId, String playerName) + { + return executeUpdate(DELETE_CLAN_MEMBER, new ColumnInt("clanid", clanId), new ColumnVarChar("name", 100, playerName)) == 1; + } + + public void updateMember(int clanId, String playerName, String role) + { + executeUpdate(UPDATE_CLAN_MEMBER, new ColumnVarChar("clanRole", 100, role) , new ColumnInt("clanid", clanId), new ColumnVarChar("name", 100, playerName)); + } + + public void addClanRelationship(int clanId, int otherClanId, boolean trusted) + { + executeUpdate(ADD_CLAN_ALLIANCE, new ColumnInt("clanid", clanId), new ColumnInt("otherClanId", otherClanId), new ColumnBoolean("trusted", trusted)); + } + + public void updateClanRelationship(int clanId, int otherClanId, boolean trusted) + { + executeUpdate(UPDATE_CLAN_ALLIANCE, new ColumnBoolean("trusted", trusted), new ColumnInt("clanid", clanId), new ColumnInt("otherClanId", otherClanId)); + } + + public void removeClanRelationship(int clanId, int otherClanId) + { + executeUpdate(DELETE_CLAN_ALLIANCE, new ColumnInt("clanid", clanId), new ColumnInt("otherClanId", otherClanId)); + } + + public boolean addTerritoryClaim(int clanId, ClaimLocation chunk, boolean safe) + { + return executeUpdate(ADD_CLAN_TERRITORY, new ColumnInt("clanId", clanId), new ColumnVarChar("chunk", 100, chunk.toStoredString()), new ColumnBoolean("safe", safe)) == 1; + } + + public boolean addTerritoryClaims(int clanId, boolean safe, ClaimLocation... chunks) + { + int affectedRows = 0; + int size = chunks.length; + String query = "INSERT INTO clanTerritory (clanId, chunk, safe) VALUES"; + for (int i = 0; i < size; i++) + { + query += " (?, ?, ?)"; + + if (i < (size - 1)) + query += ","; + } + query += ";"; + + try (Connection connection = getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) + { + Column clanIdCol = new ColumnInt("clanId", clanId); + Column safeCol = new ColumnBoolean("safe", safe); + + int i = 0; + for (ClaimLocation claim : chunks) + { + String chunk = claim.toStoredString(); + Column chunkCol = new ColumnVarChar("chunk", 100, chunk); + clanIdCol.setValue(preparedStatement, i + 1); + chunkCol.setValue(preparedStatement, i + 2); + safeCol.setValue(preparedStatement, i + 3); + i += 3; + } + + affectedRows = preparedStatement.executeUpdate(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + + return affectedRows == size; + } + + public void addWar(int initiatorId, int clanId, int score, Timestamp currentTime) + { + executeUpdate(ADD_CLAN_WAR, new ColumnInt("initiatorId", initiatorId), new ColumnInt("clanId", clanId), new ColumnInt("score", score), + new ColumnTimestamp("created", currentTime), new ColumnTimestamp("lastUpdated", currentTime)); + } + + public boolean updateWar(int initiatorId, int clanId, int score, Timestamp lastUpdated) + { + return 1 == executeUpdate(UPDATE_CLAN_WAR, new ColumnInt("score", score), + new ColumnTimestamp("lastUpdated", lastUpdated), new ColumnInt("initiatorId", initiatorId), new ColumnInt("clanId", clanId)); + } + + public void deleteAllWar(int clanId) + { + executeUpdate(DELETE_ALL_WAR, new ColumnInt("initiatorId", clanId), new ColumnInt("clanId", clanId)); + } + +// public void addEnemy(int clanId, int otherClanId) +// { +// executeUpdate(ADD_CLAN_ENEMY, new ColumnInt("clanId", clanId), new ColumnInt("otherClanId", otherClanId)); +// } + + public void removeTerritoryClaim(int clanId, ClaimLocation chunk) + { + executeUpdate(DELETE_CLAN_TERRITORY, new ColumnInt("clanId", clanId), new ColumnVarChar("chunk", 100, chunk.toStoredString())); + } + + public void removeTerritoryClaims(int clanId) + { + executeUpdate(DELETE_CLAN_ALL_TERRITORY, new ColumnInt("clanId", clanId)); + } + + public void updateClan(int clanId, String name, String desc, String home, boolean admin, int energy, int kills, int murder, int deaths, int warWins, int warLosses, Timestamp lastOnline) + { + executeUpdate(UPDATE_CLAN, new ColumnVarChar("name", 100, name), new ColumnVarChar("desc", 100, desc), new ColumnVarChar("home", 100, home), new ColumnBoolean("admin", admin), + new ColumnInt("energy", energy), new ColumnInt("kills", kills), new ColumnInt("murder", murder), new ColumnInt("deaths", deaths), + new ColumnInt("warWins", warWins), new ColumnInt("warLosses", warLosses), new ColumnTimestamp("lastOnline", lastOnline), new ColumnInt("clanId", clanId)); + } + +// public void updateEnemy(int clanId, int otherClanId, int clanScore, int otherClanScore, int clanKills, int otherClanKills) +// { +// executeUpdate(UPDATE_CLAN_ENEMY, new ColumnInt("clanId", clanId), new ColumnInt("otherClanId", otherClanId), +// new ColumnInt("clanScore", clanScore), new ColumnInt("otherClanScore", otherClanScore), new ColumnInt("clanKills", clanKills), +// new ColumnInt("otherClanKills", otherClanKills), new ColumnInt("clanId", clanId), new ColumnInt("otherClanId", otherClanId)); +// } + + public int getServerId() + { + return _serverId; + } + + public boolean updateClanGenerator(int clanId, String generator, int generatorStock) + { + return executeUpdate(UPDATE_CLAN_GENERATOR, new ColumnVarChar("generator", 140, generator), new ColumnInt("generatorStock", generatorStock), new ColumnInt("clanId", clanId)) + > 0; + } + + public void updateTerritoryClaim(ClaimLocation chunk, boolean safe) + { + executeUpdate(UPDATE_CLAN_TERRITORY, new ColumnBoolean("safe", safe), new ColumnVarChar("chunk", 100, chunk.toStoredString())); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/ClanTerritory.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/ClanTerritory.java new file mode 100644 index 00000000..3ad0dcd5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/ClanTerritory.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.core.repository; + +import org.bukkit.Location; + +import mineplex.game.clans.core.ClaimLocation; + +public class ClanTerritory +{ + public ClanTerritory(ClaimLocation loc, String owner, boolean safe) + { + ClaimLocation = loc; + Owner = owner; + Safe = safe; + } + + public boolean Safe; + public String Owner = ""; + public ClaimLocation ClaimLocation; + + public boolean isSafe(Location location) + { + if (Owner.equals("Spawn")) + { + return location.getY() > 190; + } + + return Safe; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanAllianceToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanAllianceToken.java new file mode 100644 index 00000000..c749feec --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanAllianceToken.java @@ -0,0 +1,7 @@ +package mineplex.game.clans.core.repository.tokens; + +public class ClanAllianceToken +{ + public String ClanName; + public boolean Trusted; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanEnemyToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanEnemyToken.java new file mode 100644 index 00000000..8fb9e1ed --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanEnemyToken.java @@ -0,0 +1,12 @@ +package mineplex.game.clans.core.repository.tokens; + +import java.sql.Timestamp; + +public class ClanEnemyToken +{ + public boolean Initiator; + public String EnemyName; + public int Score; + public int Kills; + public Timestamp TimeFormed; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanMemberToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanMemberToken.java new file mode 100644 index 00000000..9fab8c68 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanMemberToken.java @@ -0,0 +1,10 @@ +package mineplex.game.clans.core.repository.tokens; + +import java.util.UUID; + +public class ClanMemberToken +{ + public String Name; + public UUID PlayerUUID; + public String ClanRole; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanTerritoryToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanTerritoryToken.java new file mode 100644 index 00000000..d7c6cbfd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanTerritoryToken.java @@ -0,0 +1,10 @@ +package mineplex.game.clans.core.repository.tokens; + +public class ClanTerritoryToken +{ + public String ClanName; + public int ClanId; + public String ServerName; + public String Chunk; + public boolean Safe; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanToken.java new file mode 100644 index 00000000..64fc1722 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanToken.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.core.repository.tokens; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +public class ClanToken +{ + public int Id; + public String Name; + public String Description; + public String Home; + public boolean Admin; + public int Energy; + public int Kills; + public int Murder; + public int Deaths; + public int WarWins; + public int WarLosses; + public int EloRating; + public String GeneratorBuyer; + public int GeneratorStock; + public Timestamp DateCreated; + public Timestamp LastOnline; + + public List Members = new ArrayList(); + public List Territories = new ArrayList(); + public List Alliances = new ArrayList(); + public List WarsIn = new ArrayList(); + public List WarsOut = new ArrayList(); +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanWarToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanWarToken.java new file mode 100644 index 00000000..ad917de7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/ClanWarToken.java @@ -0,0 +1,8 @@ +package mineplex.game.clans.core.repository.tokens; + +import mineplex.game.clans.core.war.ClanWarData; + +public class ClanWarToken +{ + public ClanWarData WarData; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/SimpleClanToken.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/SimpleClanToken.java new file mode 100644 index 00000000..e7fd13ca --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/repository/tokens/SimpleClanToken.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.core.repository.tokens; + +public class SimpleClanToken +{ + + private String _clanName = ""; + public String getClanName() { return _clanName; } + + private String _clanRole; + public String getClanRole() { return _clanRole; } + + private String _homeServer; + public String getHomeServer() { return _homeServer; } + + private int _clanId; + public int getClanId() { return _clanId; } + + public SimpleClanToken(String clanName, String clanRole, String homeServer, int clanId) + { + _clanName = clanName; + _clanRole = clanRole; + _homeServer = homeServer; + _clanId = clanId; + } + + public SimpleClanToken() { } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/war/ClanWarData.java b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/war/ClanWarData.java new file mode 100644 index 00000000..d286b697 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans.Core/src/mineplex/game/clans/core/war/ClanWarData.java @@ -0,0 +1,122 @@ +package mineplex.game.clans.core.war; + +import java.sql.Timestamp; + +public class ClanWarData +{ + private String _clanA; + private String _clanB; + private volatile int _clanAPoints; + private Timestamp _timeFormed; + private Timestamp _lastUpdated; + private long _cooldown; + + public ClanWarData(String clanA, String clanB, int clanAPoints, Timestamp timeFormed, Timestamp lastUpdated, long cooldown) + { + _clanA = clanA; + _clanB = clanB; + _clanAPoints = clanAPoints; + _timeFormed = timeFormed; + _lastUpdated = lastUpdated; + _cooldown = cooldown; + } + + public String getClanA() + { + return _clanA; + } + + public String getClanB() + { + return _clanB; + } + + public int getClanAPoints() + { + return _clanAPoints; + } + + public int getClanBPoints() + { + return -_clanAPoints; + } + + public int getPoints(String clan) + { + if (_clanA.equals(clan)) + return getClanAPoints(); + else if (_clanB.equals(clan)) + return getClanBPoints(); + + throw new RuntimeException("ClanWarData::getPoints Invalid Clan for War. ClanA: " + _clanA + ", ClanB: " + _clanB + ", Lookup Clan: " + clan); + } + + public int getPoints() + { + return _clanAPoints; + } + + public Timestamp getTimeFormed() + { + return _timeFormed; + } + + public Timestamp getLastUpdated() + { + return _lastUpdated; + } + + public void setLastUpdated(Timestamp lastUpdated) + { + _lastUpdated = lastUpdated; + } + + public long getCooldown() + { + return _cooldown; + } + + public void setCooldown(long cooldown) + { + _cooldown = System.currentTimeMillis() + cooldown; + } + + public boolean isOnCooldown() + { + return _cooldown >= System.currentTimeMillis(); + } + + public void resetPoints() + { + update(); + + _clanAPoints = 0; + } + + public void increment(String clan) + { + update(); + + if (_clanA.equals(clan)) + _clanAPoints++; + else if (_clanB.equals(clan)) + _clanAPoints--; + else throw new RuntimeException("ClanWarData::increment Invalid Clan for War. ClanA: " + _clanA + ", ClanB: " + _clanB + ", Lookup Clan: " + clan); + } + + public void set(String clan, int points) + { + update(); + + if (_clanA.equals(clan)) + _clanAPoints++; + else if (_clanB.equals(clan)) + _clanAPoints--; + else throw new RuntimeException("ClanWarData::increment Invalid Clan for War. ClanA: " + _clanA + ", ClanB: " + _clanB + ", Lookup Clan: " + clan); + } + + private void update() + { + setLastUpdated(new Timestamp(System.currentTimeMillis())); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/plugin.yml b/Plugins[Modified]/Mineplex.Game.Clans/plugin.yml new file mode 100644 index 00000000..0d9f0bb9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/plugin.yml @@ -0,0 +1,4 @@ +name: Clans +main: mineplex.game.clans.Clans +version: 1.0 +loadbefore: [MineplexAnticheat] \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/pom.xml b/Plugins[Modified]/Mineplex.Game.Clans/pom.xml new file mode 100644 index 00000000..02d16f54 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + Clans + mineplex-game-clans + + + + ${project.groupId} + mineplex-game-clans-core + ${project.version} + + + ${project.groupId} + mineplex-minecraft-game-classcombat + ${project.version} + + + ${project.groupId} + mineplex-clansqueue-common + ${project.version} + + + diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java new file mode 100644 index 00000000..b405b494 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java @@ -0,0 +1,245 @@ +package mineplex.game.clans; + +import static mineplex.core.Managers.require; + +import java.io.File; +import java.io.IOException; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +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.account.CoreClientManager; +import mineplex.core.achievement.AchievementManager; +//import mineplex.core.antihack.AntiHack; +//import mineplex.core.antihack.guardians.GuardianManager; +import mineplex.core.aprilfools.AprilFoolsManager; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.chat.Chat; +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.MinecraftVersion; +import mineplex.core.common.Pair; +import mineplex.core.common.events.ServerShutdownEvent; +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.fallingblock.FallingBlocks; +import mineplex.core.friend.FriendManager; +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.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; +import mineplex.core.rankGiveaway.eternal.EternalGiveawayManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.report.ReportManager; +import mineplex.core.report.ReportPlugin; +import mineplex.core.resourcepack.ResourcePackManager; +import mineplex.core.serverConfig.ServerConfiguration; +import mineplex.core.stats.StatsManager; +import mineplex.core.status.ServerStatusManager; +import mineplex.core.teleport.Teleport; +import mineplex.core.twofactor.TwoFactorAuth; +import mineplex.core.updater.FileUpdater; +import mineplex.core.updater.Updater; +import mineplex.core.visibility.VisibilityManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.freeze.ClansFreezeManager; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.shop.building.BuildingShop; +import mineplex.game.clans.shop.farming.FarmingShop; +import mineplex.game.clans.shop.mining.MiningShop; +import mineplex.game.clans.shop.pvp.PvpShop; +import mineplex.game.clans.spawn.travel.TravelShop; +import mineplex.game.clans.world.WorldManager; +import net.minecraft.server.v1_8_R3.MinecraftServer; + +public class Clans extends JavaPlugin +{ + + private static final String MAP = "Season 5.5"; + public static boolean HARDCORE = false; + + // Modules + private CoreClientManager _clientManager; + private DonationManager _donationManager; + private ClansManager _clansManager; + + @Override + public void onEnable() + { + try + { + HARDCORE = new File(new File(".").getCanonicalPath() + File.separator + "Hardcore.dat").exists(); + } + catch (IOException e) + { + e.printStackTrace(); + } + Bukkit.setSpawnRadius(0); + + // Configs + getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS); + getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY)); + saveConfig(); + + // Logger.initialize(this); + + // Static Modules + CommandCenter.Initialize(this); + _clientManager = new CoreClientManager(this); + CommandCenter.Instance.setClientManager(_clientManager); + + ItemStackFactory.Initialize(this, false); + + DelayedTask.Initialize(this); + + Recharge.Initialize(this); + require(VisibilityManager.class); + // new ProfileCacheManager(this); + + _donationManager = require(DonationManager.class); + + new FallingBlocks(this); + + new ServerConfiguration(this, _clientManager); + + PacketHandler packetHandler = require(PacketHandler.class); + IncognitoManager incognito = new IncognitoManager(this, _clientManager, packetHandler); + PreferencesManager preferenceManager = new PreferencesManager(this, incognito, _clientManager); + + incognito.setPreferencesManager(preferenceManager); + + ServerStatusManager serverStatusManager = new ServerStatusManager(this, _clientManager, new LagMeter(this, _clientManager)); + + // TODO: Add spawn locations to a configuration file of some sort? + Give.Initialize(this); + + Teleport teleport = new Teleport(this, _clientManager); + Portal portal = new Portal(); + new FileUpdater(GenericServer.CLANS_HUB); + + ClansFreezeManager clansFreeze = new ClansFreezeManager(this, _clientManager); + + Punish punish = new Punish(this, _clientManager, true); + + DisguiseManager disguiseManager = require(DisguiseManager.class); + Creature creature = new Creature(this); + + //AntiHack antiHack = require(AntiHack.class); + GuardianManager guardianManager = require(GuardianManager.class); + + //Bukkit.getScheduler().runTask(this, antiHack::enableAnticheat); + + new EternalGiveawayManager(this, _clientManager, serverStatusManager); + + BlockRestore blockRestore = require(BlockRestore.class); + + IgnoreManager ignoreManager = new IgnoreManager(this, _clientManager, preferenceManager, portal); + + StatsManager statsManager = new StatsManager(this, _clientManager); + EloManager eloManager = new EloManager(this, _clientManager); + AchievementManager achievementManager = new AchievementManager(statsManager, _clientManager, _donationManager, incognito, eloManager); + Chat chat = require(Chat.class); + new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, require(FriendManager.class), chat); + + new MemoryFix(this); + new FoodDupeFix(this); + new Explosion(this, blockRestore); + InventoryManager inventory = new InventoryManager(this, _clientManager); + ResourcePackManager resourcePackManager = new ResourcePackManager(this, portal); + resourcePackManager.setResourcePack(new Pair[] + { + //Pair.create(MinecraftVersion.Version1_8, "http://file.mineplex.com/ResClans.zip"), + //Pair.create(MinecraftVersion.Version1_9, "http://file.mineplex.com/ResClans19.zip") + Pair.create(MinecraftVersion.Version1_8, "http://198.20.72.74/ResClans.zip"), + Pair.create(MinecraftVersion.Version1_9, "http://198.20.72.74/ResClans19.zip") + }, true); + + 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)); + + // Enable custom-gear related managers + new CustomTagFix(this, packetHandler); + GearManager customGear = new GearManager(this, packetHandler, _clientManager, _donationManager); + + HologramManager hologram = require(HologramManager.class); + _clansManager = new ClansManager(this, serverStatusManager.getCurrentServerName(), incognito, packetHandler, punish, _clientManager, _donationManager, preferenceManager, blockRestore, statsManager, teleport, chat, customGear, hologram, inventory); + new Recipes(this); + new Farming(this); + new BuildingShop(_clansManager, _clientManager, _donationManager); + new PvpShop(_clansManager, _clientManager, _donationManager); + new FarmingShop(_clansManager, _clientManager, _donationManager); + new TravelShop(_clansManager, _clientManager, _donationManager); + new MiningShop(_clansManager, _clientManager, _donationManager); + new WorldManager(this); + + require(TwoFactorAuth.class); + + AprilFoolsManager.getInstance(); + + // Disable spigot item merging + for (World world : getServer().getWorlds()) + { + // Disable item merging + ((CraftWorld) world).getHandle().spigotConfig.itemMerge = 0; + } + + //Updates + require(Updater.class); + + MinecraftServer.getServer().getPropertyManager().setProperty("debug", false); + SpigotConfig.debug = false; + } + + public static String prettifyName(Material material) + { + String name = ""; + String[] words = material.toString().split("_"); + + for (String word : words) + { + word = word.toLowerCase(); + name += word.substring(0, 1).toUpperCase() + word.substring(1) + " "; + } + + return name; + } + + @Override + public void onDisable() + { + // Need to notify WorldEventManager of server shutdown, this seemed like + // the only decent way to do it + _clansManager.onDisable(); + + getServer().getPluginManager().callEvent(new ServerShutdownEvent(this)); + } + + public static String getMap() + { + return MAP; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Farming.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Farming.java new file mode 100644 index 00000000..64035a9c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Farming.java @@ -0,0 +1,38 @@ +package mineplex.game.clans; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.UtilItem; +import mineplex.core.itemstack.ItemStackFactory; + +public class Farming extends MiniPlugin +{ + public Farming(JavaPlugin plugin) + { + super("Farming", plugin); + } + + @EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = true) + public void BlockBreak(BlockBreakEvent event) + { + if (event.getBlock().getType() != Material.LEAVES) + return; + + if (UtilItem.matchesMaterial(event.getPlayer().getItemInHand(), Material.SHEARS)) + return; + + Location dropLocation = event.getBlock().getLocation().add(0.5, 0.5, 0.5); + + if (Math.random() > 0.9) + event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.APPLE)); + + if (Math.random() > 0.999) + event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Recipes.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Recipes.java new file mode 100644 index 00000000..8615db3d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/Recipes.java @@ -0,0 +1,274 @@ +package mineplex.game.clans; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.material.SmoothBrick; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemStackFactory; + +public class Recipes extends MiniPlugin +{ + public Recipes(JavaPlugin plugin) + { + super("Recipes", plugin); + + ItemStack boosterAxe = ItemStackFactory.Instance.CreateStack(Material.GOLD_AXE, (byte) 0, 1, "Booster Axe", false); + ShapedRecipe goldAxe = new ShapedRecipe(boosterAxe); + goldAxe.shape("#MM","#SM","#S#"); + goldAxe.setIngredient('M', Material.GOLD_BLOCK); + goldAxe.setIngredient('S', Material.STICK); + UtilServer.getServer().addRecipe(goldAxe); + + ItemStack powerAxe = ItemStackFactory.Instance.CreateStack(Material.DIAMOND_AXE, (byte) 0, 1, "Power Axe", false); + ShapedRecipe diamondAxe = new ShapedRecipe(powerAxe); + diamondAxe.shape("#MM","#SM","#S#"); + diamondAxe.setIngredient('M', Material.DIAMOND_BLOCK); + diamondAxe.setIngredient('S', Material.STICK); + UtilServer.getServer().addRecipe(diamondAxe); + + + ShapedRecipe bricks = new ShapedRecipe(new ItemStack(Material.SMOOTH_BRICK, 1)); + bricks.shape("XX", "XX"); + bricks.setIngredient('X', new SmoothBrick(Material.COBBLESTONE)); + UtilServer.getServer().addRecipe(bricks); + + + ItemStack boosterSword = ItemStackFactory.Instance.CreateStack(Material.GOLD_SWORD, (byte) 0, 1, "Booster Sword", false); + ShapedRecipe goldSword = new ShapedRecipe(boosterSword); + goldSword.shape("M","M","S"); + goldSword.setIngredient('M', Material.GOLD_BLOCK); + goldSword.setIngredient('S', Material.STICK); + UtilServer.getServer().addRecipe(goldSword); + + ItemStack powerSword = ItemStackFactory.Instance.CreateStack(Material.DIAMOND_SWORD, (byte) 0, 1, "Power Sword", false); + ShapedRecipe diamondSword = new ShapedRecipe(powerSword); + diamondSword.shape("M","M","S"); + diamondSword.setIngredient('M', Material.DIAMOND_BLOCK); + diamondSword.setIngredient('S', Material.STICK); + UtilServer.getServer().addRecipe(diamondSword); + + //Iron Door + ShapedRecipe ironDoor = new ShapedRecipe(new ItemStack(Material.IRON_DOOR, 1)); + ironDoor.shape("I","I"); + ironDoor.setIngredient('I', Material.IRON_INGOT); + UtilServer.getServer().addRecipe(ironDoor); + + //Chain Helm + ShapedRecipe chainHelm = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_HELMET, 1)); + + chainHelm.shape("SIS","I#I"); + + chainHelm.setIngredient('I', Material.IRON_INGOT); + chainHelm.setIngredient('S', Material.GOLD_INGOT); + + UtilServer.getServer().addRecipe(chainHelm); + + //Chain Chest + ShapedRecipe chainChest = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_CHESTPLATE, 1)); + + chainChest.shape("I#I","SIS","ISI"); + + chainChest.setIngredient('I', Material.IRON_INGOT); + chainChest.setIngredient('S', Material.GOLD_INGOT); + + UtilServer.getServer().addRecipe(chainChest); + + //Chain Legs + ShapedRecipe chainLegs = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_LEGGINGS, 1)); + + chainLegs.shape("ISI","S#S","I#I"); + + chainLegs.setIngredient('I', Material.IRON_INGOT); + chainLegs.setIngredient('S', Material.GOLD_INGOT); + + UtilServer.getServer().addRecipe(chainLegs); + + //Chain Boots + ShapedRecipe chainBoots = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_BOOTS, 1)); + + chainBoots.shape("S#S","I#I"); + + chainBoots.setIngredient('I', Material.IRON_INGOT); + chainBoots.setIngredient('S', Material.GOLD_INGOT); + + UtilServer.getServer().addRecipe(chainBoots); + + //Chain Helm + ShapedRecipe chainHelm2 = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_HELMET, 1)); + + chainHelm2.shape("SIS","I#I"); + + chainHelm2.setIngredient('I', Material.GOLD_INGOT); + chainHelm2.setIngredient('S', Material.IRON_INGOT); + + UtilServer.getServer().addRecipe(chainHelm2); + + //Chain Chest + ShapedRecipe chainChest2 = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_CHESTPLATE, 1)); + + chainChest2.shape("I#I","SIS","ISI"); + + chainChest2.setIngredient('I', Material.GOLD_INGOT); + chainChest2.setIngredient('S', Material.IRON_INGOT); + + UtilServer.getServer().addRecipe(chainChest2); + + //Chain Legs + ShapedRecipe chainLegs2 = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_LEGGINGS, 1)); + + chainLegs2.shape("ISI","S#S","I#I"); + + chainLegs2.setIngredient('I', Material.GOLD_INGOT); + chainLegs2.setIngredient('S', Material.IRON_INGOT); + + UtilServer.getServer().addRecipe(chainLegs2); + + //Chain Boots + ShapedRecipe chainBoots2 = new ShapedRecipe(new ItemStack(Material.CHAINMAIL_BOOTS, 1)); + + chainBoots2.shape("S#S","I#I"); + + chainBoots2.setIngredient('I', Material.GOLD_INGOT); + chainBoots2.setIngredient('S', Material.IRON_INGOT); + + UtilServer.getServer().addRecipe(chainBoots2); + + ShapedRecipe stonebrick = new ShapedRecipe(new ItemStack(Material.SMOOTH_BRICK, 1)); + stonebrick.shape("SS#", "SS#"); + stonebrick.setIngredient('S', Material.STONE); + UtilServer.getServer().addRecipe(stonebrick); + + stonebrick = new ShapedRecipe(new ItemStack(Material.SMOOTH_BRICK, 1)); + stonebrick.shape("#SS", "#SS"); + stonebrick.setIngredient('S', Material.STONE); + UtilServer.getServer().addRecipe(stonebrick); + + stonebrick = new ShapedRecipe(new ItemStack(Material.SMOOTH_BRICK, 1)); + stonebrick.shape("###", "SS#", "SS#"); + stonebrick.setIngredient('S', Material.STONE); + UtilServer.getServer().addRecipe(stonebrick); + + stonebrick = new ShapedRecipe(new ItemStack(Material.SMOOTH_BRICK, 1)); + stonebrick.shape("###", "#SS", "#SS"); + stonebrick.setIngredient('S', Material.STONE); + UtilServer.getServer().addRecipe(stonebrick); + + + } + + @EventHandler(priority = EventPriority.LOW) + public void addLore(PrepareItemCraftEvent event) + { + if (event.getView().getPlayer() instanceof Player) + { + Player player = ((Player) event.getView().getPlayer()); + CraftingInventory inv = (CraftingInventory)event.getInventory(); + + ItemStack itemStack = inv.getResult(); + + if (UtilGear.isWeapon(itemStack)) + { + ItemStackFactory.Instance.addOwnerLore(itemStack, player.getName() + " Crafting"); + inv.setResult(itemStack); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void ReplaceDoor(PrepareItemCraftEvent event) + { + if (event.getRecipe().getResult() == null) + return; + + Material type = event.getRecipe().getResult().getType(); + + if (type != Material.WOOD_DOOR && type != Material.WOODEN_DOOR) + return; + + if (!(event.getInventory() instanceof CraftingInventory)) + return; + + CraftingInventory inv = (CraftingInventory)event.getInventory(); + + //Feedback + ItemStack result = ItemStackFactory.Instance.CreateStack(Material.IRON_DOOR); + inv.setResult(result); + } + + @EventHandler(priority = EventPriority.HIGH) + public void DenySword(PrepareItemCraftEvent event) + { + if (event.getRecipe().getResult() == null) + return; + + Material type = event.getRecipe().getResult().getType(); + + if (type != Material.DIAMOND_SWORD && type != Material.GOLD_SWORD && + type != Material.DIAMOND_AXE && type != Material.GOLD_AXE) + return; + + if (!(event.getInventory() instanceof CraftingInventory)) + return; + + CraftingInventory inv = (CraftingInventory)event.getInventory(); + + for (ItemStack cur : inv.getMatrix()) + if (cur != null) + if (cur.getType() == Material.GOLD_BLOCK || cur.getType() == Material.DIAMOND_BLOCK) + return; + + String name = ItemStackFactory.Instance.GetName(event.getRecipe().getResult(), true); + String matName = "Gold"; + if (type == Material.DIAMOND_AXE || type == Material.DIAMOND_SWORD) + matName = "Diamond"; + + //Feedback + ItemStack result = ItemStackFactory.Instance.CreateStack(36, (byte)0, 1, "§r" + C.cGray + "Recipe changed for " + F.item(name) + ".", + new String[] {C.cGray + "Use " + F.item(matName + " Blocks") + " instead of " + F.item(matName + " Ingots") + "."}); + + inv.setResult(result); + } + + @EventHandler(priority = EventPriority.HIGH) + public void DenyGeneral(PrepareItemCraftEvent event) + { + if (event.getRecipe().getResult() == null) + return; + + Material type = event.getRecipe().getResult().getType(); + + if ( + type != Material.GOLDEN_APPLE && + type != Material.GOLDEN_CARROT && + type != Material.ENDER_CHEST && + type != Material.ENCHANTMENT_TABLE && + type != Material.BREWING_STAND && + type != Material.TNT) + return; + + if (!(event.getInventory() instanceof CraftingInventory)) + return; + + CraftingInventory inv = (CraftingInventory)event.getInventory(); + + String name = ItemStackFactory.Instance.GetName(event.getRecipe().getResult(), true); + + //Feedback + ItemStack result = ItemStackFactory.Instance.CreateStack(36, (byte)0, 1, + "§r" + C.cGray + "Crafting of " + F.item(name) + " is disabled.", new String[] {}); + + inv.setResult(result); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/BedStatus.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/BedStatus.java new file mode 100644 index 00000000..08f3c89b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/BedStatus.java @@ -0,0 +1,9 @@ +package mineplex.game.clans.clans; + +public enum BedStatus +{ + EXISTS_AND_UNOBSTRUCTED, + EXISTS_AND_OBSTRUCTED, + DESTROYED, + DOESNT_EXIST; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ChunkData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ChunkData.java new file mode 100644 index 00000000..9eccb517 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ChunkData.java @@ -0,0 +1,28 @@ +package mineplex.game.clans.clans; + +import org.bukkit.ChatColor; +import org.bukkit.Color; + +public class ChunkData +{ + + private int _x; + public int getX() { return _x; } + + private int _z; + public int getZ() { return _z; } + + private ChatColor _color; + public ChatColor getColor() { return _color; } + + private String _clanName; + public String getClanName() { return _clanName; } + + public ChunkData(int x, int z, ChatColor color, String clanName) + { + _x = x; + _z = z; + _color = color; + _clanName = clanName; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanEnergyManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanEnergyManager.java new file mode 100644 index 00000000..f61253bc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanEnergyManager.java @@ -0,0 +1,84 @@ +package mineplex.game.clans.clans; + +import com.mineplex.clansqueue.common.ClansQueueMessenger; +import com.mineplex.clansqueue.common.messages.QueuePauseUpdateMessage; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.shop.energy.EnergyShop; + +public class ClanEnergyManager extends MiniPlugin implements Runnable +{ + + private final ClansManager _clansManager; + private volatile boolean _paused; + private int tickCount; + + public ClanEnergyManager(ClansManager clansManager) + { + super("Clan Energy"); + + _clansManager = clansManager; + + new EnergyShop(this, clansManager.getClientManager(), clansManager.getDonationManager()); + + // Wait 5 seconds and then tick every 60 seconds + _plugin.getServer().getScheduler().runTaskTimer(_plugin, this, 20 * 5, 20 * 60); + ClansQueueMessenger.getMessenger(UtilServer.getServerName()).registerListener(QueuePauseUpdateMessage.class, (pause, origin) -> + { + if (pause.ServerName.equals(UtilServer.getServerName())) + { + _paused = pause.Paused; + } + }); + } + + @Override + public void run() + { + if (_paused) + { + return; + } + + tickCount++; + + for (final ClanInfo clanInfo : _clansManager.getClanMap().values()) + { + if (clanInfo.isAdmin()) + continue; + + int energyPerMinute = clanInfo.getEnergyCostPerMinute(); + int currentEnergy = clanInfo.getEnergy(); + + if (currentEnergy < energyPerMinute) + { + for (ClaimLocation chunk : clanInfo.getClaimSet()) + { + _clansManager.getClanDataAccess().unclaimSilent(chunk, true); + } + _clansManager.messageClan(clanInfo, F.main("Clans", "Your clan has ran out of energy. Land claims have been removed")); + } + else + { + clanInfo.adjustEnergy(-energyPerMinute); + if (tickCount % 5 == 0 && energyPerMinute > 0) + { + runAsync(() -> _clansManager.getClanDataAccess().updateEnergy(clanInfo)); + } + } + } + } + + public ClansManager getClansManager() + { + return _clansManager; + } + + public int convertEnergyToGold(int energy) + { + return (energy / 8) + (energy % 8 == 0 ? 0 : 1); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanEnergyTracker.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanEnergyTracker.java new file mode 100644 index 00000000..3541d812 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanEnergyTracker.java @@ -0,0 +1,69 @@ +package mineplex.game.clans.clans; + +import java.util.EnumMap; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang3.tuple.Triple; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanTips.TipType; + +public class ClanEnergyTracker extends MiniPlugin +{ + private ClansManager _clans; + private EnumMap> _updateMap; + + public ClanEnergyTracker(JavaPlugin plugin, ClansManager clans) + { + super("Clan Energy Tracker", plugin); + _clans = clans; + + _updateMap = new EnumMap<>(UpdateType.class); + _updateMap.put(UpdateType.MIN_05, Triple.of(0L, TimeUnit.HOURS.toMillis(1), new String[] { C.cRed + "Urgent", "Clan Energy is almost depleted" })); + _updateMap.put(UpdateType.MIN_10, Triple.of(TimeUnit.HOURS.toMillis(1), TimeUnit.HOURS.toMillis(4), new String[] { C.cGold + "Warning", "Clan Energy is low" })); + _updateMap.put(UpdateType.MIN_30, Triple.of(TimeUnit.HOURS.toMillis(4), TimeUnit.DAYS.toMillis(1), new String[] { C.cGold + "Notice", "Clan Energy is running low" })); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (_updateMap.containsKey(event.getType())) + { + for (ClanInfo clan : _clans.getClanMap().values()) + { + display(clan, event.getType()); + } + } + } + + private void display(ClanInfo clan, UpdateType type) + { + // No point in doing anything if nobody is online! + if (!clan.isOnlineNow()) + { + return; + } + + // Avoid divide by 0 + if (clan.getEnergyCostPerMinute() <= 0) + { + return; + } + + // Energy Remaining in milliseconds + long energyRemaining = (clan.getEnergy() / clan.getEnergyCostPerMinute()) * 60000L; + + Triple energyBounds = _updateMap.get(type); + + if (energyBounds != null && energyRemaining > energyBounds.getLeft() && energyRemaining < energyBounds.getMiddle()) + { + _clans.middleTextClan(clan, energyBounds.getRight()[0], energyBounds.getRight()[1], 20, 200, 80); + _clans.sendTipToClan(clan, TipType.ENERGY); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java new file mode 100644 index 00000000..1cbd22ec --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanInfo.java @@ -0,0 +1,830 @@ +package mineplex.game.clans.clans; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.Material; + +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; +import mineplex.game.clans.clans.tntgenerator.TntGenerator; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.tokens.ClanAllianceToken; +import mineplex.game.clans.core.repository.tokens.ClanMemberToken; +import mineplex.game.clans.core.repository.tokens.ClanTerritoryToken; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.core.repository.tokens.ClanWarToken; +import mineplex.game.clans.core.war.ClanWarData; + +public class ClanInfo +{ + private int _id = -1; + private String _name = ""; + private String _desc = ""; + private Location _home = null; + private int _energy = 4320; + + // Stats + private int _kills; + private int _murder; + private int _deaths; + private int _warWins; + private int _warLosses; + private int _eloRating; + + private boolean _admin = false; + + private Timestamp _dateCreated; + private Timestamp _lastOnline = null; + + private TntGenerator _generator; + + // Loaded from Client + private NautHashMap _memberMap = new NautHashMap(); + private NautHashMap _allyMap = new NautHashMap(); + private Set _claimSet = new HashSet<>(); + + // Wars Initiated By Others + private HashMap _warIn = new HashMap(); + // Wars Initiated By Self + private HashMap _warOut = new HashMap(); + + // Temporary + private NautHashMap _recentlyLeft = new NautHashMap<>(); + private NautHashMap _inviteeMap = new NautHashMap(); + private NautHashMap _inviterMap = new NautHashMap(); + private List _onlinePlayers = new ArrayList(); + + private NautHashMap _requestMap = new NautHashMap(); + + public ClansManager Clans; + + private BedStatus _bedStatus = null; + + + public ClanInfo(ClansManager clans, ClanToken token) + { + Clans = clans; + + _id = token.Id; + _name = token.Name; + _desc = token.Description; + _eloRating = token.EloRating; + + try + { + _home = UtilWorld.strToLoc(token.Home); + } + catch (Exception e) + { + + } + + if (_home != null) + { + if (UtilBlock.isValidBed(_home)) + { + if (_home.clone().add(0, 1,0).getBlock().getType().equals(Material.AIR)) + { + _bedStatus = BedStatus.EXISTS_AND_UNOBSTRUCTED; + } + else + { + _bedStatus = BedStatus.EXISTS_AND_OBSTRUCTED; + } + } + else + { + _bedStatus = BedStatus.DESTROYED; + } + } + else + { + _bedStatus = BedStatus.DOESNT_EXIST; + } + + _energy = token.Energy; + _admin = token.Admin; + + _dateCreated = (token.DateCreated != null) ? token.DateCreated : new Timestamp(System.currentTimeMillis()); + _lastOnline = (token.LastOnline != null) ? token.LastOnline : new Timestamp(System.currentTimeMillis()); + + for (ClanMemberToken memberToken : token.Members) + { + ClanRole role = ClanRole.valueOf(memberToken.ClanRole); + _memberMap.put(memberToken.PlayerUUID, new ClansPlayer(memberToken.Name, memberToken.PlayerUUID, role)); + } + + for (ClanTerritoryToken territoryToken : token.Territories) + { + _claimSet.add(ClaimLocation.fromStoredString(territoryToken.Chunk)); + } + + for (ClanAllianceToken allianceToken : token.Alliances) + { + _allyMap.put(allianceToken.ClanName, allianceToken.Trusted); + } + + for (ClanWarToken warToken : token.WarsIn) + { + ClanWarData warData = warToken.WarData; + _warIn.put(warData.getClanA(), warData); + } + + for (ClanWarToken warToken : token.WarsOut) + { + ClanWarData warData = warToken.WarData; + _warOut.put(warData.getClanB(), warData); + } + + try + { + if (token.GeneratorBuyer != null && token.GeneratorBuyer.length() > 0) + { + if (token.GeneratorBuyer.contains(",")) + { + // Convert to new generator format; + + for (ClanMemberToken memberToken : token.Members) + { + ClanRole role = ClanRole.valueOf(memberToken.ClanRole); + + if (role.equals(ClanRole.LEADER)) + { + token.GeneratorBuyer = memberToken.PlayerUUID.toString(); + break; + } + } + + System.out.println("Clans> Converted " + _name + "'s generator to the new format."); + } + + _generator = new TntGenerator(token.GeneratorBuyer); + _generator.setStock(token.GeneratorStock); + + Clans.getClanDataAccess().updateGenerator(this, null); + } + } + catch (Exception e) + { + + } + } + + public int getClaims() + { + return getClaimSet().size(); + } + + public int getClaimsMax() + { + if (ssAdmin()) + return 1000; + + return Math.min(8, 2 + getMembers().size()); + } + + public int getAllies() + { + return getAllyMap().size(); + } + + public int getAlliesMax() + { + return getAlliesMaxWithMemberCountOf(_memberMap.size()); + } + + public int getAlliesMaxWithMemberCountOf(int memberCount) + { + if (ssAdmin()) + { + return 1000; + } + + return Math.max(2, 6 - memberCount); + } + + public BedStatus getBedStatus() + { + return _bedStatus; + } + + public void setBedStatus(BedStatus bedStatus) + { + _bedStatus = bedStatus; + } + + public boolean isRequested(String clan) + { + if (!getRequestMap().containsKey(clan)) + return false; + + if (System.currentTimeMillis() > getRequestMap().get(clan) + (Clans.getInviteExpire() * 60000)) + return false; + + return true; + } + + public boolean isInvited(String player) + { + if (!getInviteeMap().containsKey(player)) + return false; + + if (System.currentTimeMillis() > getInviteeMap().get(player) + (Clans.getInviteExpire() * 60000)) + return false; + + return true; + } + + public boolean isMember(Player player) + { + return getMembers().containsKey(player.getUniqueId()); + } + + public boolean isMember(UUID uuid) + { + return getMembers().containsKey(uuid); + } + + public boolean isAlly(String other) + { + return getAllyMap().containsKey(other); + } + + public boolean isAlly(ClanInfo other) + { + if (other == null) + { + return false; + } + + return isAlly(other.getName()); + } + + public boolean isSelf(String other) + { + return getName().equals(other); + } + + public boolean isNeutral(String other) + { + return (!isAlly(other) && !isSelf(other)); + } + + public long getTimer() + { + int penalty = 0; + return System.currentTimeMillis() + (penalty * 1000); + } + + public boolean getTrust(String clan) + { + if (!getAllyMap().containsKey(clan)) + return false; + + return getAllyMap().get(clan); + } + + public LinkedList mDetails(Player caller) + { + LinkedList stringList = new LinkedList(); + + stringList.add(F.main("Clans", Clans.getClanUtility().mRel(Clans.getClanUtility().relPC(caller, this), getName() + " Information;", true))); + // stringList.add(F.value("Desc", _desc)); + + // Age + stringList.add(F.value("Age", + UtilTime.convertString(System.currentTimeMillis() - _dateCreated.getTime(), 1, TimeUnit.FIT))); + + // Home + if (Clans.getClanUtility().relPC(caller, this) == ClanRelation.SELF) + stringList.add(F.value("Home", UtilWorld.locToStrClean(getHome()))); + + // Land + stringList.add(F.value("Territory", getClaims() + "/" + getClaimsMax())); + + // Member count + stringList.add(F.value("Members", getSize() + "/" + getMaxSize())); + + // Energy + int energy = getEnergy(); + int costPerHour = getEnergyCostPerMinute() * 60; + stringList.add(" "); + stringList.add(F.value("Clan Energy", "" + energy)); +// stringList.add(F.value("Max Energy", "" + getEnergyMax())); + stringList.add(F.value("Energy Drain/Hour", "" + costPerHour)); + if (costPerHour > 0) + stringList.add(F.value("Hours Left", "" + energy / costPerHour)); + stringList.add(" "); + + // Ally String + String allySorted = ""; + HashSet allyUnsorted = new HashSet(); + + for (String allyName : getAllyMap().keySet()) + allyUnsorted.add(allyName); + + for (String cur : UtilAlg.sortKey(allyUnsorted)) + allySorted += Clans.getClanUtility().mRel(Clans.getClanUtility().relPC(caller, Clans.getClanMap().get(cur)), cur, false) + + ", "; + + stringList.add(F.value("Allies", allySorted)); + + // Members + String members = ""; + for (ClansPlayer cur : UtilAlg.sortSet(getMembers().values(), new ClansPlayerComparator())) + { + String name = C.listValueOff + cur.getPlayerName(); + if (cur.isOnline()) + name = C.listValueOn + cur.getPlayerName(); + + if (cur.getRole() == ClanRole.LEADER) + members += C.listValue + "L." + name + C.mBody + ", "; + + if (cur.getRole() == ClanRole.ADMIN) + members += C.listValue + "A." + name + C.mBody + ", "; + + if (cur.getRole() == ClanRole.MEMBER) + members += C.listValue + "M." + name + C.mBody + ", "; + + if (cur.getRole() == ClanRole.RECRUIT) + members += C.listValue + "R." + name + C.mBody + ", "; + } + stringList.add(F.value("Members", members)); + + return stringList; + } + + public LinkedList mTerritory() + { + LinkedList stringList = new LinkedList(); + + stringList.add(F.main("Clans", getName() + " Territory;")); + + getClaimSet().stream().map(ClaimLocation::toStoredString).forEach(stringList::add); + + return stringList; + } + + public void inform(String message, String ignore) + { + for (UUID cur : getMembers().keySet()) + { + Player player = UtilPlayer.searchExact(cur); + + if (player == null) + continue; + + if (player.getName().equals(ignore)) + continue; + + UtilPlayer.message(player, F.main("Clans", message)); + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1f, 2f); + } + } + + public void inform(String top, String bottom, String ignore) + { + for (UUID cur : getMembers().keySet()) + { + Player player = UtilPlayer.searchExact(cur); + + if (player == null) + continue; + + if (player.getName().equals(ignore)) + continue; + + UtilTextMiddle.display(top, bottom, 20, 100, 20, player); + } + } + + public String getName() + { + return _name; + } + + public String getDesc() + { + return _desc; + } + + public void setDesc(String desc) + { + _desc = desc; + } + + public NautHashMap getMembers() + { + return _memberMap; + } + + public Set getClaimSet() + { + return _claimSet; + } + + public Location getHome() + { + return _home != null ? _home.clone() : null; + } + + public void setHome(Location loc) + { + _home = loc; + } + + public boolean ssAdmin() + { + return _admin; + } + + public void setAdmin(boolean admin) + { + _admin = admin; + } + + public NautHashMap getInviterMap() + { + return _inviterMap; + } + + public NautHashMap getInviteeMap() + { + return _inviteeMap; + } + + public NautHashMap getAllyMap() + { + return _allyMap; + } + + public NautHashMap getRequestMap() + { + return _requestMap; + } + + public Timestamp getDateCreated() + { + return _dateCreated; + } + + public Timestamp getLastOnline() + { + return _lastOnline; + } + + public void setLastOnline(Timestamp lastOnline) + { + _lastOnline = lastOnline; + } + + public boolean isOnlineNow() + { + return _onlinePlayers.size() > 0; + } + + public boolean isOnline() + { + return isOnlineNow(); + } + + public TntGenerator getGenerator() + { + return _generator; + } + + public void setGenerator(TntGenerator generator) + { + _generator = generator; + } + + public boolean isAdmin() + { + return _admin; + } + + public int getId() + { + return _id; + } + + public void setId(int id) + { + _id = id; + } + + public int getEnergy() + { + if (_energy > getEnergyMax()) + { + _energy = getEnergyMax(); + } + + return _energy; + } + + public String getEnergyLeftString() + { + if (getEnergyCostPerMinute() > 0) + return UtilTime.convertString(60000L * getEnergy() / getEnergyCostPerMinute(), 1, TimeUnit.FIT); + + return "Infinite"; + } + + public int getKills() + { + return _kills; + } + + public void addKills(int amount) + { + _kills += amount; + } + + public int getMurder() + { + return _murder; + } + + public void addMurder(int amount) + { + _murder += amount; + } + + public int getDeaths() + { + return _deaths; + } + + public void addDeaths(int amount) + { + _deaths += amount; + } + + public int getWarWins() + { + return _warWins; + } + + public void addWarWins(int amount) + { + _warWins += amount; + } + + public int getWarLosses() + { + return _warLosses; + } + + public void addWarLosses(int amount) + { + _warLosses += amount; + } + + public int getEloRating() + { + return _eloRating; + } + + public void addEloRating(int amount) + { + _eloRating += amount; + } + + public ClanWarData getWarData(ClanInfo against) + { + ClanWarData data = null; + + data = _warIn.get(against.getName()); + if (data == null) data = _warOut.get(against.getName()); + + return data; + } + + public int getWarPoints(ClanInfo against) + { + int warPoints = 0; + + if (against != null) + { + ClanWarData data = _warIn.get(against.getName()); + if (data != null) + { + warPoints = data.getClanBPoints(); + } + else if ((data = _warOut.get(against.getName())) != null) + { + warPoints = data.getClanAPoints(); + } + } + + return warPoints; + } + + public String getFormattedWarPoints(ClanInfo clan) + { + String warString = ""; + int warPoints = getWarPoints(clan); + + String prefix; + if (warPoints >= 5) prefix = C.cPurple; + else if (warPoints <= -5) prefix = C.cRed; + else prefix = C.cWhite; + + warString += prefix; + if (warPoints > 0) warString += "+"; + warString += warPoints; + + return warString; + } + + public void addWar(ClanWarData war) + { + if (war.getClanA().equals(getName())) + _warOut.put(war.getClanB(), war); + else if (war.getClanB().equals(getName())) + _warIn.put(war.getClanA(), war); + else throw new RuntimeException("Failed to add war to clan `" + getName() + "` ClanA: " + war.getClanA() + ", ClanB: " + war.getClanB()); + } + + public List getWars() + { + List wars = new LinkedList(); + wars.addAll(_warIn.values()); + wars.addAll(_warOut.values()); + return wars; + } + + public void clearWar(String againstClan) + { + _warIn.remove(againstClan); + _warOut.remove(againstClan); + } + + public boolean isEnemy(ClanInfo againstClan) + { + int warPoints = getWarPoints(againstClan); + return warPoints >= 5 || warPoints <= -5; + } + + public void adjustEnergy(int energy) + { + _energy += energy; + } + + public int getClaimCount() + { + return _claimSet.size(); + } + + public int getSize() + { + return _memberMap.size(); + } + + public int getMaxSize() + { + if (ssAdmin()) + return 1000; + + return 20; + } + + public int getEnergyMax() + { + // 10080 = 7 days of minutes + return Math.max(10080, getEnergyCostPerMinute() * 60 * 24 * 7); + } + + public int getEnergyCostPerMinute() + { + return (getSize() * getClaimCount()); + } + + public int getEnergyPurchasableMinutes() + { + return getEnergyPurchasable() / getEnergyCostPerMinute(); + } + + public int getEnergyPurchasable() + { + return Math.max(getEnergyMax() - getEnergy(), 0); + } + + public List getOnlinePlayers() + { + ArrayList players = new ArrayList(_onlinePlayers.size()); + for (UUID uuid : _onlinePlayers) + { + players.add(UtilPlayer.searchExact(uuid)); + } + return players; + } + + public Player[] getOnlinePlayersArray() + { + Player[] players = new Player[_onlinePlayers.size()]; + for (int i = 0; i < _onlinePlayers.size(); i++) + { + players[i] = UtilPlayer.searchExact(_onlinePlayers.get(i)); + } + return players; + } + + public int getOnlinePlayerCount() + { + return _onlinePlayers.size(); + } + + public void playerOnline(Player player) + { + ClansPlayer clansPlayer = _memberMap.get(player.getUniqueId()); + + _onlinePlayers.add(player.getUniqueId()); + clansPlayer.setPlayerName(player.getName()); + clansPlayer.setOnline(true); + } + + public void playerOnline(String player) + { + Player p = UtilPlayer.searchExact(player); + if (p != null) playerOnline(p); + } + + public void playerOffline(String player) + { + Player p = UtilPlayer.searchExact(player); + if (p != null) playerOffline(p); + } + + @Override + public String toString() + { + return _id + "," + _name; + } + + public void playerOffline(Player player) + { + ClansPlayer clansPlayer = _memberMap.get(player.getUniqueId()); + + if (clansPlayer != null) + { + clansPlayer.setOnline(false); + } + + _onlinePlayers.remove(player.getUniqueId()); + } + + public Set getMemberNameSet() + { + HashSet set = new HashSet(); + + for (ClansPlayer cp : _memberMap.values()) + { + set.add(cp.getPlayerName()); + } + + return set; + } + + public ClansPlayer getClansPlayerFromName(String playerName) + { + for (ClansPlayer cp : _memberMap.values()) + { + if (cp.getPlayerName().equals(playerName)) + return cp; + } + + return null; + } + + public String getBedStatusStr() + { + return _bedStatus == BedStatus.DESTROYED ? C.cRed + "Destroyed" : (_bedStatus == BedStatus.DOESNT_EXIST ? C.cWhite + "None" : (_bedStatus == BedStatus.EXISTS_AND_OBSTRUCTED ? C.cRed + "Obstructed" : (_bedStatus == BedStatus.EXISTS_AND_UNOBSTRUCTED ? C.cGreen + UtilWorld.locToStrClean(_home) : "N/A"))); + } + + public void left(String name) + { + _recentlyLeft.put(name, System.currentTimeMillis()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanRole.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanRole.java new file mode 100644 index 00000000..d7eb15b5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanRole.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.clans; + +public enum ClanRole +{ + NONE(0, "None"), RECRUIT(100, "Recruit"), MEMBER(500, "Member"), ADMIN(1000, "Admin"), LEADER(Integer.MAX_VALUE, "Leader"); + + private int _powerValue; + private String _friendlyName; + + ClanRole(int powerValue, String friendlyName) + { + _powerValue = powerValue; + _friendlyName = friendlyName; + } + + public boolean has(ClanRole role) + { + return getPowerValue() >= role.getPowerValue(); + } + + public String getFriendlyName() + { + return _friendlyName; + } + + public int getPowerValue() + { + return _powerValue; + } +} + diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanTips.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanTips.java new file mode 100644 index 00000000..c89a9ff9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClanTips.java @@ -0,0 +1,256 @@ +package mineplex.game.clans.clans; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.preferences.Preference; +import mineplex.core.preferences.PreferencesManager; +import mineplex.game.clans.clans.event.ClanTipEvent; +import mineplex.game.clans.clans.event.PlayerClaimTerritoryEvent; +import mineplex.game.clans.clans.event.PlayerEnterTerritoryEvent; +import mineplex.game.clans.clans.event.PlayerUnClaimTerritoryEvent; +import net.minecraft.server.v1_8_R3.EnumDirection; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.LinkedList; + +public class ClanTips extends MiniPlugin +{ + private PreferencesManager _preferences; + private ClansManager _clans; + + public ClanTips(final JavaPlugin plugin, final ClansManager clans, final PreferencesManager preferences) + { + super("Clans Tips", plugin); + + _clans = clans; + _preferences = preferences; + } + + @EventHandler + public void onEnterTerritory(final PlayerEnterTerritoryEvent event) + { + if (event.getLastTerritory().equals(event.getNewTerritory())) + { + return; + } + + final Player player = event.getPlayer(); + final String newTerritory = event.getNewTerritory(); + + if (_preferences.get(player).isActive(Preference.CLAN_TIPS)) + { + if (newTerritory.equals("Fields")) + { + displayTip(TipType.ENTER_FIELDS, player); + } + else if (newTerritory.equals("Shop") && event.isSafe()) + { + displayTip(TipType.ENTER_SHOP, player); + } + else if (newTerritory.equals("Borderlands")) + { + displayTip(TipType.ENTER_BORDERLANDS, player); + } + else if (newTerritory.equals("Spawn")) + { + displayTip(TipType.ENTER_SPAWN, player); + } + } + } + + @EventHandler + public void onClaimTerritory(final PlayerClaimTerritoryEvent event) + { + if (event.getClan().getClaimCount() == 0) + { + displayTip(TipType.FIRST_CLAIM_SETHOME, event.getClaimer()); + + // Place New + boolean bedPlaced = UtilBlock.placeBed(event.getClaimer().getLocation(), BlockFace.valueOf(EnumDirection.fromAngle(event.getClaimer().getLocation().getYaw()).name()), true, true); + + if (!bedPlaced) + { + UtilPlayer.message(event.getClaimer(), F.main("Clans", "This is not a suitable place for a bed.")); + return; + } + + // Cleanup old + if (event.getClan().getHome() != null) + { + System.out.println("<-old bed cleanup-> <--> " + UtilBlock.deleteBed(event.getClan().getHome())); + } + + // Task + _clans.getClanDataAccess().setHome(event.getClan(), event.getClaimer().getLocation(), event.getClaimer().getName()); + + return; + } + displayTip(TipType.CLAIM, event.getClaimer()); + } + + @EventHandler + public void onUnClaimTerritory(final PlayerUnClaimTerritoryEvent event) + { + displayTip(TipType.UNCLAIM, event.getUnClaimer()); + } + + public void displayTip(TipType tip, Player player) + { + if (tip == null) + { + return; + } + + if (player == null) + { + return; + } + + if (!_preferences.get(player).isActive(Preference.CLAN_TIPS) && !tip._ignorePreferences) + { + return; + } + + ClanTipEvent event = new ClanTipEvent(tip, player); + + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + UtilPlayer.message(player, " "); + UtilPlayer.message(player, tip._messages); + + if (!tip._ignorePreferences) + { + UtilPlayer.message(player, C.cGray + "(You can disable these Clans Tips in the " + F.elem("/prefs") + " menu.)"); + } + + UtilPlayer.message(player, " "); + } + + public static enum TipType + { + UNCLAIM( + new String[] { + C.cDAquaB + "You unclaimed some Clan Territory!", + C.cAqua + "When territory is unclaimed, it cannot be reclaimed by anyone for 30 minutes." + }), + + CLAIM( + new String[] { + C.cDAquaB + "You claimed some Clan Territory!", + C.cAqua + "Clan Territory is an area of the map that only your Clan is allowed to edit! This means that you can build a base and stash your loot safely inside.", + C.cAqua + "Each territory is a 16x16 area, which extends from bedrock to the sky!", C.cGreen + "The borders are marked with glowstone." + }), + + ENTER_FIELDS( + new String[] { + C.cDRedB + "Fields", + C.cRed + "Fields is a very lucrative area, filled with ores that periodically respawn over time. This is a great place to get a large amount of resources for your clan; however, be aware of other clans who may also be after the riches buried within the fields." + }), + + ENTER_SHOP( + new String[] { + C.cDGreenB + "Shops", + C.cGreen + "Shops is a safe area where combat is disabled between players! Use this safety to purchase food, building blocks, armor, weapons, and other valuable resources. Be careful when leaving though, others may be hiding just outside the gates, eager to steal your recent purchases." + }), + + ENTER_BORDERLANDS( + new String[] { + C.cDRedB + "Borderlands", + C.cRed + "The Borderlands are the very outer reaches of the map, out here you can not edit the terrain. Be careful as very powerful boss monsters will periodically spawn out here! Don't try to fight them alone! If you do manage to slay one of these powerful beasts, you'll be handsomely rewarded with powerful gear or legendary weapons." + }), + + ENTER_SPAWN( + new String[] { + C.cDGreenB + "Spawn", + C.cGreen + "Spawn is a Safe Zone where you spawn after dying. No one can attack you here, and you cannot attack anyone else. If you have set your Clan Home, you are able to teleport to it from Spawns." + }), + + FIRST_CLAIM_SETHOME( + new String[] { + C.cDAquaB + "First Claim", + C.cAqua + "Congratulations on your first Clan Claim.", + C.cAqua + "We have automatically placed your Clan Home where you are currently standing.", + C.cAqua + "In the future, to set your Clan Home elsewhere, use the " + F.elem("/c sethome") + " command.", + C.cAqua + "You can return to your Clan Home by using " + F.elem("/c home") + C.cAqua + ", but remember, you must be in a Safe Spawn location to do this.", + C.cAqua + "When you die and respawn, you are also given an option to spawn at your Clan Home." + }), + + DOMINANCE_RIP( + new String[] { + C.cDAquaB + "Lost War Point", + C.cAqua + "You were killed by another Clan and they have gained 1 War Point against you.", + C.cAqua + "If your War Points with them reaches -25, they will get to besiege your Territory, giving them access to cannon it for 30 minutes." + }), + + DOMINANCE_NOOICE( + new String[] { + C.cDAquaB + "Gained War Point", + C.cAqua + "You killed someone in another Clan and you have gained 1 War Point against them.", + C.cAqua + "If your War Points with them reaches +25, you will get to besiege their Territory, giving you access to cannon it for 30 minutes." + }), + + ENERGY( + new String[] { + C.cDAquaB + "Energy", + C.cAqua + "To top up your energy, go to the Shop and buy some in the Energy Shop.", + C.cAqua + "To find the Shop, look at your map (use " + C.cYellow + "/map" + C.cAqua + " if you don't have one) and go to either the top-most highlighted area, or the bottom-most highlighted area.", + }), + + NPC_RIPPARONI( + new String[] { + C.cDAqua + "Logout NPC", + C.cAqua + "When you quit Clans, a copy of you will remain in the game for 30 seconds. Other players are able to kill this copy and take your items. Make sure you quit somewhere safe!", + }), + + SETHOME( + new String[] { + C.cDAqua + "Clan Home", + C.cAqua + "Your Clan Home is a bed in your Territory which you can teleport to from the Spawn Islands. However, you are unable to teleport to your Clan Home if the bed is broken, blocks have been placed above the bed, or enemies are in your Territory." + }), + MOUNT_CANNON( + new String[] { + C.cDAqua + "Meownon", + C.cAqua + "Congratulations on your new purchase! You are now in possesion, of the one, and only, Meownon 3000.24! " + C.Italics + "we are not responsible for any injuries caused by the meownon, or any related products. stay safe kids." + }), + ENTER_NETHER( + new String[] { + C.cDRedB + "The Nether", + C.cRed + "The Nether is a dangerous place full of powerful mobs and hazardous terrain! However, the mobs here drop powerful Ancient Runes, which can be used to strengthen your gear, making your clan even more fearsome than before!" + }), + ; + + // this is only LinkedList because UtilPlayer.message wants it + private LinkedList _messages; + private boolean _ignorePreferences; + + TipType(String[] messages) + { + this(messages, false); + } + + TipType(String[] messages, boolean ignorePreferences) + { + _messages = new LinkedList<>(); + + for (String message : messages) + { + _messages.add(message); + } + + _ignorePreferences = ignorePreferences; + } + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansAdmin.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansAdmin.java new file mode 100644 index 00000000..bf810210 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansAdmin.java @@ -0,0 +1,963 @@ +package mineplex.game.clans.clans; + +import java.util.ArrayList; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInput; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilPlayerBase; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.core.war.ClanWarData; + +public class ClansAdmin +{ + public enum Perm implements Permission + { + USE_ADMIN_COMMANDS, + } + + private ClansManager Clans; + + public ClansAdmin(ClansManager clans) + { + Clans = clans; + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.USE_ADMIN_COMMANDS, true, true); + PermissionGroup.CMOD.setPermission(Perm.USE_ADMIN_COMMANDS, false, true); + } + + public void command(Player caller, String[] args) + { + if (!Clans.getClientManager().Get(caller).hasPermission(Perm.USE_ADMIN_COMMANDS) && !caller.isOp()) + { + UtilPlayerBase.message(caller, C.mHead + "Permissions> " + C.mBody + "You do not have permission to do that."); + return; + } + + if (!UtilServer.isTestServer()) + { + StringBuilder cmd = new StringBuilder("/c"); + for (String a : args) + { + cmd.append(" ").append(a); + } + for (int i = 0; i < cmd.length(); i++) + { + if (cmd.charAt(i) == '`') + { + cmd.setCharAt(i, '\''); + } + } + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", + new SlackMessage("Clans Command Logger", "crossed_swords", caller.getName() + " has issued command `" + cmd.toString() + "` on " + UtilServer.getServerName() + "."), + true); + } + + if (args.length == 1) + help(caller); + + else if (args[1].equalsIgnoreCase("help") || args[1].equalsIgnoreCase("h")) + help(caller); + + else if (args[1].equalsIgnoreCase("set") || args[1].equalsIgnoreCase("mimic")) + setMimic(caller, args); + + else if (args[1].equalsIgnoreCase("create")) + create(caller, args); + + else if (args[1].equalsIgnoreCase("disband") || args[1].equalsIgnoreCase("delete") || args[1].equalsIgnoreCase("d")) + delete(caller, args); + + else if (args[1].equalsIgnoreCase("invite") || args[1].equalsIgnoreCase("i")) + invite(caller, args); + + else if (args[1].equalsIgnoreCase("promote")) + promote(caller, args); + + else if (args[1].equalsIgnoreCase("demote")) + demote(caller, args); + + else if (args[1].equalsIgnoreCase("kick") || args[1].equalsIgnoreCase("k")) + kick(caller, args); + + else if (args[1].equalsIgnoreCase("ally") || args[1].equalsIgnoreCase("a")) + ally(caller, args); + +// else if (args[1].equalsIgnoreCase("trust")) +// trust(caller, args); + + else if (args[0].equalsIgnoreCase("neutral") || args[0].equalsIgnoreCase("neut") || args[0].equalsIgnoreCase("n")) + neutral(caller, args); + + else if (args[1].equalsIgnoreCase("claim") || args[1].equalsIgnoreCase("c")) + claim(caller); + + else if (args[1].equalsIgnoreCase("unclaim") || args[1].equalsIgnoreCase("uc")) + unclaim(caller, args); + + else if (args[1].equalsIgnoreCase("home") || args[1].equalsIgnoreCase("h")) + home(caller, args); + + else if (args[1].equalsIgnoreCase("safe")) + safe(caller); + + else if (args[1].equalsIgnoreCase("autoclaim")) + autoclaim(caller); + + else if (args[1].equalsIgnoreCase("wp")) + wp(caller, args); + + else if (args[1].equalsIgnoreCase("rename")) + rename(caller, args); + + else if (args[1].equalsIgnoreCase("timer")) + resetTime(caller, args); + + else + help(caller); + } + + private void help(Player caller) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Admin Commands List;")); + + UtilPlayer.message(caller, F.help("/c x create ", "Create Admin Clan", ChatColor.GOLD)); + + UtilPlayer.message(caller, F.help("/c x set ", "Set Mimic Clan", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x wp [remove/set/add] ", "Modify war points", ChatColor.GOLD)); + + UtilPlayer.message(caller, F.help("/c x home (set)", "Teleport to Mimic Home", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x invite ", "Invite Player to Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x promote ", "Promote Player in Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x demote ", "Demote Player in Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x kick ", "Kick Player from Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x ally ", "Send Alliance to Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x neutral ", "Set Neutrality", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x enemy ", "Start Invasion", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x rename ", "Change the name of Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x claim", "Claim Territory for Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x unclaim (all)", "Unclaim Territory for Mimic", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x delete", "Delete Mimic Clan", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x autoclaim", "AutoClaim for Mimic Clan", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c x timer ", "Reset Clan Create Timer", ChatColor.GOLD)); + UtilPlayer.message(caller, F.main("Mimic Clan", Clans.Get(caller).getMimic())); + } + + private void resetTime(Player caller, String[] args) + { + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not enter a player name")); + return; + } + + Player player = UtilPlayer.searchOnline(caller, args[2], true); + + if (player != null) + { + Clans.resetLeftTimer(player.getUniqueId()); + UtilPlayer.message(caller, F.main("Clans Admin", "Reset Clan create timer for " + F.name(player.getName()))); + } + } + + private void autoclaim(Player caller) + { + Clans.Get(caller).setAutoClaim(!Clans.Get(caller).isAutoClaim()); + + UtilPlayer.message(caller, F.main("Clans Admin", F.oo("Auto Claim", Clans.Get(caller).isAutoClaim()))); + } + + public void setMimic(Player caller, String[] args) + { + if (args.length < 3) + { + if (Clans.Get(caller).getMimic().length() > 0) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You are no longer mimicing " + F.elem("Clan " + Clans.Get(caller).getMimic()) + ".")); + Clans.Get(caller).setMimic(""); + } + else + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input a Clan/Player.")); + + return; + } + + ClanInfo clan = Clans.getClanUtility().searchClanPlayer(caller, args[2], true); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Invalid Clan/Player.")); + return; + } + + //Set Mimic + Clans.Get(caller).setMimic(clan.getName()); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You are mimicing " + F.elem("Clan " + clan.getName()) + ".")); + } + + public ClanInfo getMimic(Player caller, boolean inform) + { + String mimic = Clans.Get(caller).getMimic(); + + if (mimic.length() == 0) + return null; + + ClanInfo clan = Clans.getClanUtility().searchClanPlayer(caller, mimic, true); + + if (clan == null) + { + if (inform) + UtilPlayer.message(caller, F.main("Clans Admin", "You are not mimicing a Clan.")); + + return null; + } + + return clan; + } + + public void create(final Player caller, final String[] args) + { + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input a Clan name.")); + return; + } + + if (!UtilInput.valid(args[2])) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Invalid characters in Clan name.")); + return; + } + + if (args[2].length() < Clans.getNameMin()) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Clan name too short. Minimum length is " + (Clans.getNameMin()) + ".")); + return; + } + + if (args[2].length() > Clans.getNameMax()) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Clan name too long. Maximum length is " + (Clans.getNameMax()) + ".")); + return; + } + + if (!Clans.getBlacklist().allowed(args[2])) + { + UtilPlayer.message(caller, F.main("Clans Admin", "That name is blacklisted, please choose another one.")); + } + + if (Clans.getClan(args[2]) != null) + { + UtilPlayer.message(caller, F.main("Clans Admin", F.elem("Clan " + args[2]) + " already exists.")); + return; + } + + Clans.getClientManager().checkPlayerNameExact(new Callback() + { + public void run(final Boolean nameExists) + { + Bukkit.getServer().getScheduler().runTask(Clans.getPlugin(), new Runnable() + { + public void run() + { + if (nameExists) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Clan name cannot be a Player name.")); + } + else + { + Clans.getClanDataAccess().create(caller.getName(), args[2], true, new Callback() + { + @Override + public void run(ClanInfo data) + { + if (data != null) + { + //Inform + UtilServer.broadcast(F.main("Clans Admin", caller.getName() + " formed " + F.elem("Admin Clan " + args[2]) + ".")); + + // Set Mimic + Clans.Get(caller).setMimic(args[2]); + + // Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You are mimicing Clan " + args[2] + ".")); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "There was an error creating a clan! Try again later")); + } + } + }); + } + } + }); + } + }, args[2]); + } + + public void delete(final Player caller, String[] args) + { + final ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + //Task + Clans.getClanDataAccess().delete(clan, new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + //Inform + UtilServer.broadcast(F.main("Clans Admin", caller.getName() + " disbanded " + F.elem("Clan " + clan.getName()) + ".")); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "There was an error disbanding your clan! Try again later")); + } + } + }); + } + + public void wp(Player caller, String[] args) + { + ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (args.length < 5) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not supply an operation, value, and clan name.")); + return; + } + + ClanInfo clanAgainst = Clans.getClan(args[4]); + + if (clanAgainst == null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Invalid Clan against provided.")); + return; + } + + String operation = args[2]; + int value; + + try + { + value = Integer.parseInt(args[3]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Invalid value provided.")); + return; + } + + if (operation.equalsIgnoreCase("remove")) + { + ClanWarData war = clan.getWarData(clanAgainst); + + if (war != null) + { + war.set(clan.getName(), war.getClanAPoints() - value); + + Clans.getClanDataAccess().updateWar(clan, clanAgainst, war, success -> + { + UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(war.getClanB()))); + Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + }); + } + else + { + UtilPlayer.message(caller, F.main("Clans Admin", "There is no war between those two clans!")); + return; + } + } + else if (operation.equalsIgnoreCase("set")) + { + ClanWarData war = clan.getWarData(clanAgainst); + + if (war != null) + { + war.set(clanAgainst.getName(), value); + + Clans.getClanDataAccess().updateWar(clan, clanAgainst, war, success -> + { + UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(war.getClanB()))); + Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + }); + } + else + { + Clans.getClanDataAccess().war(clan, clanAgainst, value, data -> + { + UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(data.getClanB()))); + Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + }); + } + } + else if (operation.equalsIgnoreCase("add")) + { + ClanWarData war = clan.getWarData(clanAgainst); + + if (war != null) + { + war.set(clanAgainst.getName(), war.getClanAPoints() + value); + + Clans.getClanDataAccess().updateWar(clan, clanAgainst, war, success -> + { + UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(war.getClanB()))); + Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + }); + } + else + { + Clans.getClanDataAccess().war(clan, clanAgainst, value, data -> + { + UtilPlayer.message(caller, F.main("Clans Admin", "Updated war points against " + F.elem(data.getClanB()))); + Clans.messageClan(clan, F.main("Clans", "Your war points with " + F.elem(clanAgainst.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + Clans.messageClan(clanAgainst, F.main("Clans", "Your war points with " + F.elem(clan.getName()) + " have been edited by " + F.elem(caller.getName()) + "!")); + }); + } + } + else + { + UtilPlayer.message(caller, F.main("Clans Admin", "Invalid operation provided.")); + } + } + + public void invite(Player caller, String[] args) + { + ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input an invitee.")); + return; + } + + Player target = UtilPlayer.searchOnline(caller, args[2], true); + if (target == null) + return; + + //Inform + clan.inform(caller.getName() + " invited " + target.getName() + " to join Clan " + clan.getName() + ".", caller.getName()); + UtilPlayer.message(caller, F.main("Clans Admin", "You invited " + target.getName() + " to join " + F.elem("Clan " + clan.getName()) + ".")); + UtilPlayer.message(target, F.main("Clans Admin", caller.getName() + " invited you to join " + F.elem("Clan " + clan.getName()) + ".")); + + //Task + Clans.getClanDataAccess().invite(clan, target.getName(), caller.getName()); + } + + public void promote(Player caller, String[] args) + { + ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input player to promote.")); + return; + } + + String target = UtilPlayer.searchCollection(caller, args[2], clan.getMemberNameSet(), "Clan Member", true); + ClansPlayer clansPlayer = clan.getClansPlayerFromName(target); + + if (target == null || clansPlayer == null) + return; + + if (clansPlayer.getRole() == ClanRole.LEADER) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You cannot promote " + F.name(target) + " any further.")); + return; + } + + //Task + String newRank = "?"; + if (clansPlayer.getRole() == ClanRole.RECRUIT) + { + Clans.getClanDataAccess().role(clan, clansPlayer.getUuid(), ClanRole.MEMBER); + newRank = "Member"; + } + else if (clansPlayer.getRole() == ClanRole.MEMBER) + { + Clans.getClanDataAccess().role(clan, clansPlayer.getUuid(), ClanRole.ADMIN); + newRank = "Admin"; + } + else if (clansPlayer.getRole() == ClanRole.ADMIN) + { + Clans.getClanDataAccess().role(clan, clansPlayer.getUuid(), ClanRole.LEADER); + newRank = "Leader"; + } + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You promoted " + target + " to " + newRank + " in Mimic Clan.")); + clan.inform(caller.getName() + " promoted " + target + " to " + newRank + ".", null); + } + + public void demote(Player caller, String[] args) + { + ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input player to demote.")); + return; + } + + String target = UtilPlayer.searchCollection(caller, args[2], clan.getMemberNameSet(), "Clan Member", true); + ClansPlayer clansPlayer = clan.getClansPlayerFromName(target); + if (target == null || clansPlayer == null) + return; + + if (clansPlayer.getRole() == ClanRole.RECRUIT) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You cannot demote " + F.name(target) + " any further.")); + return; + } + + //Task + String newRank = "?"; + if (clansPlayer.getRole() == ClanRole.MEMBER) + { + Clans.getClanDataAccess().role(clan, clansPlayer.getUuid(), ClanRole.RECRUIT); + newRank = "Recruit"; + } + else if (clansPlayer.getRole() == ClanRole.ADMIN) + { + Clans.getClanDataAccess().role(clan, clansPlayer.getUuid(), ClanRole.MEMBER); + newRank = "Member"; + } + else if (clansPlayer.getRole() == ClanRole.LEADER) + { + Clans.getClanDataAccess().role(clan, clansPlayer.getUuid(), ClanRole.ADMIN); + newRank = "Admin"; + } + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You demoted " + target + " to " + newRank + " in Mimic Clan.")); + clan.inform(F.main("Clans Admin", caller.getName() + " demoted " + target + " to " + newRank + "."), null); + } + + public void kick(final Player caller, String[] args) + { + final ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input a Player to kick.")); + return; + } + + final String target = UtilPlayer.searchCollection(caller, args[2], clan.getMemberNameSet(), "Clan Member", true); + ClansPlayer clansPlayer = clan.getClansPlayerFromName(target); + + if (target == null || clansPlayer == null) + return; + + final Player player = UtilPlayer.searchExact(clansPlayer.getUuid()); + + Callback callback = new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + //Inform + if (player != null) + UtilPlayer.message(player, F.main("Clans Admin", caller.getName() + " kicked you from " + F.elem("Clan " + clan.getName()) + ".")); + UtilPlayer.message(caller, F.main("Clans Admin", "You kicked " + target + " from your Clan.")); + clan.inform(F.main("Clans Admin", caller.getName() + " kicked " + target + " from your Clan."), caller.getName()); + } + else + { + UtilPlayer.message(caller, F.main("Clans Admin", "There was an error processing your request")); + } + } + }; + + if (player != null) Clans.getClanDataAccess().leave(clan, player, callback); + else Clans.getClanDataAccess().leave(clan, clansPlayer, callback); + } + + public void ally(Player caller, String[] args) + { + ClanInfo cA = getMimic(caller, true); + + if (cA == null) + return; + + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input a Clan to ally.")); + return; + } + + ClanInfo cB = Clans.getClanUtility().searchClanPlayer(caller, args[2], true); + + if (cB == null) + return; + + if (cA.isSelf(cB.getName())) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You cannot ally with yourself.")); + return; + } + + if (cA.isAlly(cB.getName())) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You are already allies with " + F.elem("Clan " + cB.getName()) + ".")); + return; + } + + if (cB.isRequested(cA.getName())) + { + //Task + Clans.getClanDataAccess().ally(cA, cB, caller.getName()); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You accepted alliance with Clan " + cB.getName() + ".")); + cA.inform(caller.getName() + " accepted alliance with Clan " + cB.getName() + ".", caller.getName()); + cB.inform("Clan " + cA.getName() + " has accepted alliance with you.", null); + } + else + { + //Task + Clans.getClanDataAccess().requestAlly(cA, cB, caller.getName()); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You requested alliance with Clan " + cB.getName() + ".")); + cA.inform(caller.getName() + " has requested alliance with Clan " + cB.getName() + ".", caller.getName()); + cB.inform("Clan " + cA.getName() + " has requested alliance with you.", null); + } + } + + + public void rename(Player caller, String[] args) + { + ClanInfo cA = getMimic(caller, true); + + if (cA == null) + return; + + if (args.length < 3) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You did not input a new name.")); + return; + } + + String name = args[2]; + + final ClanToken clan = new ClanToken(); + + // Populate simple fields + clan.Id = cA.getId(); + clan.Name = cA.getName(); + clan.Description = cA.getDesc(); + clan.Home = UtilWorld.locToStr(cA.getHome()); + clan.Admin = cA.isAdmin(); + clan.Energy = cA.getEnergy(); + clan.Kills = cA.getKills(); + clan.Murder = cA.getMurder(); + clan.Deaths = cA.getDeaths(); + clan.WarWins = cA.getWarWins(); + clan.WarLosses = cA.getWarLosses(); + clan.GeneratorBuyer = cA.getGenerator().getBuyer().toString(); + clan.GeneratorStock = cA.getGenerator().getStock(); + clan.DateCreated = cA.getDateCreated(); + clan.LastOnline = cA.getLastOnline(); + clan.EloRating = cA.getEloRating(); + +// clan.Members = cA.getMembers(); + + } + +// public void trust(Player caller, String[] args) +// { +// ClanInfo callerClan = getMimic(caller, true); +// +// if (callerClan == null) +// return; +// +// if (args.length < 3) +// { +// UtilPlayer.message(caller, F.main("Clans Admin", "You did not input a Clan to enemy.")); +// return; +// } +// +// ClanInfo otherClan = Clans.getClanUtility().searchClanPlayer(caller, args[2], true); +// +// if (otherClan == null) +// return; +// +// if (!callerClan.isAlly(otherClan.getName())) +// { +// UtilPlayer.message(caller, F.main("Clans Admin", "You must be allied to trust a clan!")); +// return; +// } +// +// //Task +// if (Clans.getClanDataAccess().trust(callerClan, otherClan, caller.getName())) +// { +// //Inform +// UtilPlayer.message(caller, F.main("Clans Admin", "You gave trust to Clan " + otherClan.getName() + ".")); +// callerClan.inform(caller.getName() + " has given trust to Clan " + otherClan.getName() + ".", caller.getName()); +// otherClan.inform("Clan " + callerClan.getName() + " has given trust to you.", null); +// } +// else +// { +// //Inform +// UtilPlayer.message(caller, F.main("Clans Admin", "You revoked trust to Clan " + otherClan.getName() + ".")); +// callerClan.inform(caller.getName() + " has revoked trust to Clan " + otherClan.getName() + ".", caller.getName()); +// otherClan.inform("Clan " + callerClan.getName() + " has revoked trust to you.", null); +// } +// } + + public void neutral(Player caller, String[] args) + { + ClanInfo cA = getMimic(caller, true); + + if (cA == null) + return; + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a Clan to set neutrality with.")); + return; + } + + ClanInfo cB = Clans.getClanUtility().searchClanPlayer(caller, args[1], true); + + if (cB == null) + return; + + if (cB.isSelf(cA.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You prefer to think of yourself positively...")); + return; + } + + if (cB.isNeutral(cA.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You are already neutral with " + F.elem("Clan " + cB.getName()) + ".")); + return; + } + + if (cB.isAlly(cA.getName())) + { + //Task + Clans.getClanDataAccess().neutral(cA, cB, caller.getName(), true); + + //Inform + UtilPlayer.message(caller, F.main("Clans", "You revoked alliance with " + F.elem("Clan " + cB.getName()) + ".")); + cA.inform(F.name(caller.getName()) + " revoked alliance with " + F.elem("Clan " + cB.getName()) + ".", caller.getName()); + cB.inform(F.elem("Clan " + cA.getName()) + " has revoked alliance with you.", null); + + return; + } + } + + public void claim(Player caller) + { + ClanInfo clientClan = getMimic(caller, true); + + if (clientClan == null) + return; + + ClaimLocation chunk = ClaimLocation.of(caller.getLocation().getChunk()); + ClanInfo ownerClan = Clans.getClanUtility().getOwner(caller.getLocation()); + + //Already Claimed + if (ownerClan != null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "This Territory is claimed by " + + Clans.getClanUtility().mRel(Clans.getClanUtility().relPC(caller, ownerClan), ownerClan.getName(), true) + ".")); + return; + } + + //Task + Clans.getClanDataAccess().claim(clientClan.getName(), chunk, caller.getName(), false); + + //Inform + if (clientClan.getClaims() >= clientClan.getClaimsMax()) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You have claimed for that clan past their normal limit.")); + } + UtilPlayer.message(caller, F.main("Clans Admin", "You claimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".")); + clientClan.inform(caller.getName() + " claimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".", caller.getName()); + } + + public void unclaim(Player caller, String[] args) + { + if (args.length > 2) + { + if (args[2].equalsIgnoreCase("all") || args[2].equalsIgnoreCase("a")) + { + unclaimall(caller); + return; + } + } + + ClanInfo clientClan = getMimic(caller, true); + + if (clientClan == null) + return; + + ClaimLocation chunk = ClaimLocation.of(caller.getLocation().getChunk()); + ClanInfo ownerClan = Clans.getClanUtility().getOwner(caller.getLocation()); + + //Not Claimed + if (ownerClan == null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Territory is not claimed.")); + return; + } + + //Task + Clans.getClanDataAccess().unclaim(chunk, caller.getName(), true); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You unclaimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".")); + ownerClan.inform(caller.getName() + " unclaimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".", caller.getName()); + } + + public void unclaimall(Player caller) + { + ClanInfo clientClan = getMimic(caller, true); + + if (clientClan == null) + return; + + //Unclaim + ArrayList toUnclaim = new ArrayList<>(); + + for (ClaimLocation chunk : clientClan.getClaimSet()) + toUnclaim.add(chunk); + + for (ClaimLocation chunk : toUnclaim) + Clans.getClanDataAccess().unclaim(chunk, caller.getName(), true); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You unclaimed all your Clans Territory.")); + clientClan.inform(caller.getName() + " unclaimed all your Clans Territory.", caller.getName()); + } + + public void home(Player caller, String[] args) + { + if (args.length > 2) + { + if (args[2].equalsIgnoreCase("set") || args[2].equalsIgnoreCase("s")) + { + homeSet(caller); + return; + } + } + + ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (clan.getHome() == null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Your Clan has not set a Home.")); + return; + } + + if (!clan.getClaimSet().contains(ClaimLocation.of(clan.getHome().getChunk()))) + { + UtilPlayer.message(caller, F.main("Clans Admin", "Your Clan has lost its Home Territory.")); + return; + } + + //Do + Clans.getTeleport().TP(caller, clan.getHome().add(0, .6, 0)); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You teleported to your Clan Home " + UtilWorld.locToStrClean(caller.getLocation()) + ".")); + } + + public void homeSet(Player caller) + { + ClanInfo clan = getMimic(caller, true); + + if (clan == null) + return; + + if (Clans.getClanUtility().getOwner(caller.getLocation()) == null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You must set your Clan Home in your own Territory.")); + return; + } + + if (!Clans.getClanUtility().getOwner(caller.getLocation()).isSelf(clan.getName())) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You must set your Clan Home in your own Territory.")); + return; + } + + //Task + Clans.getClanDataAccess().setHome(clan, caller.getLocation(), caller.getName()); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "You set Clan Home to " + UtilWorld.locToStrClean(caller.getLocation()) + ".")); + clan.inform(caller.getName() + " set Clan Home to " + UtilWorld.locToStrClean(caller.getLocation()) + ".", caller.getName()); + } + + public void safe(Player caller) + { + ClanTerritory claim = Clans.getClanUtility().getClaim(caller.getLocation()); + + if (claim == null) + { + UtilPlayer.message(caller, F.main("Clans Admin", "You can only Safe Zone on Claimed Territory.")); + return; + } + + //Set + Clans.getClanDataAccess().safe(claim, caller.getName()); + + //Inform + UtilPlayer.message(caller, F.main("Clans Admin", "Territory Safe Zone: " + F.tf(claim.isSafe(caller.getLocation())))); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansBlocks.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansBlocks.java new file mode 100644 index 00000000..fe4755ca --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansBlocks.java @@ -0,0 +1,141 @@ +package mineplex.game.clans.clans; + +import java.util.HashSet; + +public class ClansBlocks +{ + public HashSet denyInteract = new HashSet(); + public HashSet allowInteract = new HashSet(); + + public HashSet denyUsePlace = new HashSet(); + public HashSet allowUsePlace = new HashSet(); + + public HashSet allowBreak = new HashSet(); + + public boolean denyInteract(int id) + { + if (denyInteract.isEmpty()) + { + denyInteract.add(22); //Lapis + denyInteract.add(23); //Dispenser + denyInteract.add(26); //Bed + denyInteract.add(54); //Chest + denyInteract.add(61); //Furance + denyInteract.add(62); //Furnace + denyInteract.add(64); //Wood Door + //denyInteract.add(69); //Lever + //denyInteract.add(70); //Stone Plate + denyInteract.add(71); //Iron Door + //denyInteract.add(72); //Wood Plate + //denyInteract.add(77); //Stone Button + denyInteract.add(93); //Repeater + denyInteract.add(94); //Repeater + denyInteract.add(96); //Trap Door + denyInteract.add(107); //Fence Gate + denyInteract.add(117); //Brewing Stand + denyInteract.add(146); //Trap Chest + } + + return denyInteract.contains(id); + } + + public boolean allowInteract(int id) + { + if (allowInteract.isEmpty()) + { + allowInteract.add(64); //Wood Door + //allowInteract.add(69); //Lever + //allowInteract.add(70); //Stone Plate + allowInteract.add(71); //Iron Door + //allowInteract.add(72); //Wood Plate + //allowInteract.add(77); //Stone Button + allowInteract.add(96); //Trap Door + allowInteract.add(107); //Fence Gate + } + + return allowInteract.contains(id); + } + + public boolean denyUsePlace(int id) + { + if (denyUsePlace.isEmpty()) + { + //List PLACEABLE ITEMS + denyUsePlace.add(259); //Flint & Steel + denyUsePlace.add(321); //Painting + denyUsePlace.add(323); //Sign + denyUsePlace.add(324); //Wood Door + denyUsePlace.add(326); //Water Bucket + denyUsePlace.add(327); //Lava Bucket + denyUsePlace.add(330); //Iron Door + denyUsePlace.add(331); //Redstone + denyUsePlace.add(333); //Boat + denyUsePlace.add(355); //Bed + denyUsePlace.add(356); //Redstone Repeater + denyUsePlace.add(379); //Brewing Stand + denyUsePlace.add(380); //Cauldron + denyUsePlace.add(389); //Frame + denyUsePlace.add(390); //Pot + denyUsePlace.add(404); //Comparator + denyUsePlace.add(407); //TNT Cart + denyUsePlace.add(287); //String + denyUsePlace.add(397); //Skulls + } + + if (id == 65) + return false; + + if (id > 0 && id < 256) + return true; + + return denyUsePlace.contains(id); + } + + public boolean allowUsePlace(int id) + { + if (allowUsePlace.isEmpty()) + { + allowUsePlace.add(37); //Flower + allowUsePlace.add(38); //Flower + allowUsePlace.add(65); //Ladder + } + + return allowUsePlace.contains(id); + } + + public boolean canBreak(int id) + { + if (allowBreak.isEmpty()) + { + allowBreak.add(6); //Saplings + allowBreak.add(12); //Sand + allowBreak.add(13); //Gravel + allowBreak.add(22); //Blue + allowBreak.add(30); //Web + + allowBreak.add(39); //Brown Mushroom + allowBreak.add(40); //Red Mushroom + allowBreak.add(59); //Wheat Seeds + allowBreak.add(81); //Cactus + allowBreak.add(83); //Sugar Cane + allowBreak.add(86); //Pumpkin + allowBreak.add(103); //Melon + allowBreak.add(104); //Pumpkin Stem + allowBreak.add(105); //Melon Stem + allowBreak.add(115); //Nether Wart + allowBreak.add(127); //Cocoa Plant + allowBreak.add(141); //Carrot + allowBreak.add(142); //Potato + + allowBreak.add(58); //Workbench + allowBreak.add(61); //Furnace + allowBreak.add(62); //Furnace + //allowBreak.add(116); //Enchanting + //allowBreak.add(117); //Brewing + allowBreak.add(138); //Beacon + //allowBreak.add(145); //Anvil + } + + return allowBreak.contains(id); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDataAccessLayer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDataAccessLayer.java new file mode 100644 index 00000000..73862052 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDataAccessLayer.java @@ -0,0 +1,846 @@ +package mineplex.game.clans.clans; + +import java.sql.Timestamp; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.event.ClanCreatedEvent; +import mineplex.game.clans.clans.event.ClanCreationCompleteEvent; +import mineplex.game.clans.clans.event.ClanDeleteEvent; +import mineplex.game.clans.clans.event.ClanJoinEvent; +import mineplex.game.clans.clans.event.ClanLeaveEvent; +import mineplex.game.clans.clans.event.ClanSetHomeEvent; +import mineplex.game.clans.clans.scoreboard.ClansScoreboardManager; +import mineplex.game.clans.clans.tntgenerator.TntGenerator; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.ClanRepository; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.core.war.ClanWarData; + +public class ClansDataAccessLayer +{ + private ClansManager _manager; + private ClanRepository _repository; + private ClansScoreboardManager _scoreboard; + + public ClansDataAccessLayer(ClansManager clans, ClansScoreboardManager scoreboard) + { + _manager = clans; + _scoreboard = scoreboard; + _repository = new ClanRepository(clans.getPlugin(), clans.getServerName(), true); + } + + public void delete(final ClanInfo clan, final Callback callback) + { + runAsync(new Runnable() + { + @Override + public void run() + { + final boolean out = _repository.deleteClan(clan.getId()); + + if (out) + { + runSync(new Runnable() + { + @Override + public void run() + { + deleteLocally(clan); + + if (callback != null) callback.run(out); + } + }); + } + + } + }); + } + + public void deleteLocally(ClanInfo clan) + { + // Territory Unclaim + for (ClaimLocation cur : clan.getClaimSet()) + { + _manager.getClaimMap().remove(cur); + } + + _manager.getClanMap().remove(clan.getName()); + + for (ClansPlayer player : clan.getMembers().values()) + { + _manager.getClanMemberUuidMap().remove(player.getUuid()); + } + + // Clean from Others + for (ClanInfo cur : _manager.getClanMap().values()) + { + cur.getAllyMap().remove(clan.getName()); + cur.getRequestMap().remove(clan.getName()); + cur.clearWar(cur.getName()); + } + + // Scoreboard + _scoreboard.refresh(clan); + + // Log + _manager.log("Deleted [" + clan.getName() + "]."); + + ClanDeleteEvent event = new ClanDeleteEvent(clan); + Bukkit.getServer().getPluginManager().callEvent(event); + } + + public void createAndJoin(final Player player, final String name, final Callback callback) + { + create(player.getName(), name, false, new Callback() + { + @Override + public void run(final ClanInfo clan) + { + if (clan != null) + { + runAsync(new Runnable() + { + @Override + public void run() + { + final ClanRole role = ClanRole.LEADER; + _repository.addMember(clan.getId(), player.getUniqueId(), role.toString()); + runSync(new Runnable() + { + @Override + public void run() + { + updateJoinCache(clan, player, role); + + // Log + _manager.log("Added [" + player + "] to [" + clan.getName() + "]."); + + if (callback != null) callback.run(clan); + } + }); + } + }); + } + else + { + if (callback != null) callback.run(null); + } + } + }); + } + + public void create(final String creator, final String name, final boolean admin, final Callback callback) + { + final ClanToken token = new ClanToken(); + token.Name = name; + token.Description = "No Description"; + token.Home = ""; + token.Admin = admin; + token.Energy = 4320; + + ClanCreatedEvent event = new ClanCreatedEvent(token, Bukkit.getPlayer(creator)); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + token.Id = event.getId(); + token.Name = event.getName(); + token.Description = creator; + token.Home = event.getHome(); + token.Admin = event.isAdmin(); + token.Energy = event.getEnergy(); + token.Kills = event.getKills(); + token.Murder = event.getMurders(); + token.Deaths = event.getDeaths(); + token.WarWins = event.getWarWins(); + token.WarLosses = event.getWarLosses(); + token.DateCreated = event.getDateCreated(); + token.LastOnline = event.getLastOnline(); + + runAsync(new Runnable() + { + @Override + public void run() + { + final int clanId = _repository.addClan(token); + final boolean response = clanId != -1; + + runSync(new Runnable() + { + @Override + public void run() + { + ClanInfo clanInfo = null; + + if (response) + { + token.Id = clanId; + clanInfo = new ClanInfo(_manager, token); + _manager.getClanMap().put(name, clanInfo); + _manager.log("[" + clanInfo.getName() + "] with Admin [" + admin + "] created by [" + creator + "]."); + } + + if (callback != null) callback.run(clanInfo); + + ClanCreationCompleteEvent event = new ClanCreationCompleteEvent(token, Bukkit.getPlayer(creator)); + UtilServer.getServer().getPluginManager().callEvent(event); + } + }); + } + }); + } + + public void join(final ClanInfo clan, final Player player, final ClanRole role, final Callback callback) + { + ClanJoinEvent event = new ClanJoinEvent(clan, player); + + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + runAsync(new Runnable() + { + @Override + public void run() + { + final boolean success = _repository.addMember(clan.getId(), player.getUniqueId(), role.toString()); + + runSync(new Runnable() + { + @Override + public void run() + { + if (success) + { + updateJoinCache(clan, player, role); + + // Log + _manager.log("Added [" + player + "] to [" + clan.getName() + "]."); + } + + if (callback != null) callback.run(success); + } + }); + + } + }); + } + + private void updateJoinCache(ClanInfo clan, Player player, ClanRole role) + { + if (_manager.getClanMemberUuidMap().containsKey(player.getUniqueId())) leave(_manager.getClanUtility().getClanByPlayer(player), player, null); + + // Update Clan + ClansPlayer cp = new ClansPlayer(player.getName(), player.getUniqueId(), role); + clan.getMembers().put(player.getUniqueId(), cp); + _manager.getClanMemberUuidMap().put(player.getUniqueId(), clan); + clan.getInviteeMap().remove(player.getName()); + clan.getInviterMap().remove(player.getName()); + clan.playerOnline(player); + + // Scoreboard + _scoreboard.refresh(player); + } + + public void leave(ClanInfo clan, Player player, Callback callback) + { + ClansPlayer clansPlayer = clan.getMembers().get(player.getUniqueId()); + if (clansPlayer != null) + { + leave(clan, clansPlayer, callback); + _scoreboard.refresh(player); + } + } + + public void leave(final ClanInfo clan, final ClansPlayer clansPlayer, final Callback callback) + { + if (clan == null) return; + + ClanLeaveEvent event = new ClanLeaveEvent(clan, clansPlayer); + + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + runAsync(new Runnable() + { + @Override + public void run() + { + final boolean success = _repository.removeMember(clan.getId(), clansPlayer.getPlayerName()); + + runSync(new Runnable() + { + @Override + public void run() + { + if (success) + { + // Update Clan + clan.getMembers().remove(clansPlayer.getUuid()); + _manager.getClanMemberUuidMap().remove(clansPlayer.getUuid()); + clan.playerOffline(clansPlayer.getPlayerName()); + + _manager.justLeft(clansPlayer.getUuid(), clan); + // Log + _manager.log("Removed [" + clansPlayer.getPlayerName() + "] from [" + clan.getName() + "]."); + } + + if (callback != null) callback.run(success); + } + }); + } + }); + } + + public void role(final ClanInfo clan, final UUID uuid, final ClanRole role) + { + final ClansPlayer clansPlayer = clan.getMembers().get(uuid); + + if (clansPlayer != null) + { + // Update Clan + clansPlayer.setRole(role); + + // Save + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.updateMember(clan.getId(), clansPlayer.getPlayerName(), role.toString()); + } + }); + + // Log + _manager.log("Removed [" + clansPlayer.getPlayerName() + "] from [" + clan.getName() + "]."); + } + } + + public void invite(ClanInfo clan, String player, String inviter) + { + clan.getInviteeMap().put(player, System.currentTimeMillis()); + clan.getInviterMap().put(player, inviter); + + // Log + _manager.log("Invited [" + player + "] to [" + clan.getName() + "] by [" + inviter + "]."); + } + + public void requestAlly(ClanInfo clan, ClanInfo target, String player) + { + clan.getRequestMap().put(target.getName(), System.currentTimeMillis()); + + // Log + _manager.log("Alliance Request to [" + target.getName() + "] from [" + clan.getName() + "] by [" + player + "]."); + } + + public void ally(final ClanInfo cA, final ClanInfo cB, String player) + { + // Remove Requests + cA.getRequestMap().remove(cB.getName()); + cB.getRequestMap().remove(cA.getName()); + + // Update ClansManager + cA.getAllyMap().put(cB.getName(), false); + cB.getAllyMap().put(cA.getName(), false); + + // Save + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.addClanRelationship(cA.getId(), cB.getId(), false); + _repository.addClanRelationship(cB.getId(), cA.getId(), false); + } + }); + + // Scoreboard + _scoreboard.refresh(cA); + + // Log + _manager.log("Added Ally for [" + cB.getName() + "] and [" + cA.getName() + "] by [" + player + "]."); + } + + /* + * public void enemy(final ClanInfo clan, final ClanInfo otherClan, String + * player) { runAsync(new Runnable() { + * @Override public void run() { _repository.addEnemy(clan.getId(), + * otherClan.getId()); } }); // Memory Timestamp currDate = new + * Timestamp(System.currentTimeMillis()); ClanEnemyToken clanEnemyToken = + * new ClanEnemyToken(); clanEnemyToken.Initiator = true; + * clanEnemyToken.TimeFormed = currDate; clanEnemyToken.Score = 0; + * clanEnemyToken.EnemyName = otherClan.getName(); + * clan.updateEnemy(clanEnemyToken); ClanEnemyToken otherClanEnemyToken = + * new ClanEnemyToken(); otherClanEnemyToken.Initiator = false; + * otherClanEnemyToken.TimeFormed = currDate; otherClanEnemyToken.Score = 0; + * otherClanEnemyToken.EnemyName = clan.getName(); + * otherClan.updateEnemy(otherClanEnemyToken); //Scoreboard + * _scoreboard.refresh(clan); _manager.log("Added Enemy for [" + + * clan.getName() + "] and [" + otherClan.getName() + "] by [" + player + + * "]."); } + */ + +// public boolean trust(final ClanInfo ownerClan, final ClanInfo otherClan, String player) +// { +// if (!ownerClan.getAllyMap().containsKey(otherClan.getName())) return false; +// +// final boolean trust = !ownerClan.getAllyMap().get(otherClan.getName()); +// +// // Memory +// ownerClan.getAllyMap().put(otherClan.getName(), trust); +// +// // Save +// runAsync(new Runnable() +// { +// @Override +// public void run() +// { +// _repository.updateClanRelationship(ownerClan.getId(), otherClan.getId(), trust); +// } +// }); +// +// // Scoreboard +// _scoreboard.refresh(ownerClan); +// +// // Log +// _manager.log((trust ? "Gave" : "Revoked") + " Trust [" + trust + "] to [" + otherClan.getName() + "] for [" + ownerClan.getName() + "] by [" + player + "]."); +// +// return trust; +// } + + public void neutral(final ClanInfo cA, final ClanInfo cB, String player, boolean bothClansManager) + { + // Update ClansManager + cA.getAllyMap().remove(cB.getName()); + cB.getAllyMap().remove(cA.getName()); + + // Save + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.removeClanRelationship(cA.getId(), cB.getId()); + _repository.removeClanRelationship(cB.getId(), cA.getId()); + } + }); + + // Scoreboard + _scoreboard.refresh(cA); + + // Log + _manager.log("Added Neutral between [" + cA.getName() + "] and [" + cB.getName() + "] by [" + player + "]."); + } + + public boolean claimAll(final String name, final String player, final boolean safe, final ClaimLocation... chunks) + { + if (!_manager.getClanMap().containsKey(name)) return false; + + final ClanInfo clan = _manager.getClanMap().get(name); + + // Unclaim + for (ClaimLocation chunk : chunks) + { + if (_manager.getClaimMap().containsKey(chunk)) + { + unclaim(chunk, player, false); + } + + // Memory + ClanTerritory claim = new ClanTerritory(chunk, name, safe); + clan.getClaimSet().add(chunk); + _manager.getClaimMap().put(chunk, claim); + } + + // Save + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.addTerritoryClaims(clan.getId(), safe, chunks); + + // Log + _manager.log("Successfully added [" + chunks.length + "] Claims for [" + name + "] by [" + player + "]."); + } + }); + + return true; + } + + @SuppressWarnings("deprecation") + public boolean claim(String name, final ClaimLocation chunk, String player, final boolean safe) + { + if (!_manager.getClanMap().containsKey(name)) return false; + + final ClanInfo clan = _manager.getClanMap().get(name); + + // Unclaim + if (_manager.getClaimMap().containsKey(chunk)) unclaim(chunk, player, false); + + // Memory + ClanTerritory claim = new ClanTerritory(chunk, name, safe); + clan.getClaimSet().add(chunk); + _manager.getClaimMap().put(chunk, claim); + + // Save + runAsync(() -> + { + _repository.addTerritoryClaim(clan.getId(), chunk, safe); + }); + + // Visual + Chunk c = chunk.toChunk(); + if (!clan.isAdmin()) + { + for (int x = 0; x < 16; x++) + { + for (int z = 0; z < 16; z++) + { + if (z == 0 || z == 15 || x == 0 || x == 15) + { + Block down = UtilBlock.getHighest(c.getWorld(), c.getBlock(x, 0, z).getX(), c.getBlock(x, 0, z).getZ()).getRelative(BlockFace.DOWN); + if (down.getTypeId() == 1 || down.getTypeId() == 2 || down.getTypeId() == 3 || down.getTypeId() == 12 || down.getTypeId() == 8) _manager.getBlockRestore().add(down, 89, (byte) 0, 180000, true); + } + } + } + } + + // Log + _manager.log("Added Claim for [" + name + "] at [" + chunk + "] by [" + + player + "]."); + + return true; + } + + public boolean unclaim(final ClaimLocation chunk, String player, boolean sql) + { + ClanTerritory claim = _manager.getClaimMap().remove(chunk); + + if (claim == null) + { + _manager.log("Unclaiming NULL Chunk Failed."); + return false; + } + + final ClanInfo clan = _manager.getClanMap().get(claim.Owner); + + if (clan == null) + { + _manager.log("Unclaiming from NULL Clan Failed."); + return false; + } + + // Memory + clan.getClaimSet().remove(chunk); + _manager.getUnclaimMap().put(chunk, System.currentTimeMillis()); + + // Save + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.removeTerritoryClaim(clan.getId(), chunk); + } + }); + + // Restore any glowstone blocks + Chunk c = chunk.toChunk(); + if (!clan.isAdmin()) + { + for (int x = 0; x < 16; x++) + { + for (int z = 0; z < 16; z++) + { + if (z == 0 || z == 15 || x == 0 || x == 15) + { + for (int y = 0; y < 256; y++) + { + Block block = c.getBlock(x, y, z); + if (block.getType() == Material.GLOWSTONE) + { + if (!_manager.getBlockRestore().restore(block)) block.setType(Material.STONE); + } + } + } + } + } + } + + // Log + if (player != null) _manager.log("Removed Claim for [" + clan.getName() + "] at [" + chunk + "] by [" + player + "]."); + else + _manager.log("Removed Claim for [" + clan.getName() + "] at [" + chunk + "] by [NO ONE?!]."); + + // Bed Removal + if (clan.getHome() != null && UtilWorld.chunkToStr(clan.getHome().getChunk()).equals(chunk)) + { + UtilBlock.deleteBed(clan.getHome()); + clan.setHome(null); + clan.inform("Clan has lost its Home because of a Territory loss.", null); + } + + return true; + } + + public boolean unclaimSilent(ClaimLocation chunk, boolean sql) + { + return unclaim(chunk, null, sql); + } + + public void setHome(final ClanInfo clan, Location loc, String player) + { + // Event + ClanSetHomeEvent event = new ClanSetHomeEvent(clan, Bukkit.getPlayer(player), loc); + Bukkit.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + // Memory + clan.setHome(loc); + + // Save + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.updateClan(clan.getId(), clan.getName(), clan.getDesc(), UtilWorld.locToStr(clan.getHome()), clan.isAdmin(), clan.getEnergy(), clan.getKills(), clan.getMurder(), clan.getDeaths(), clan.getWarWins(), clan.getWarLosses(), clan.getLastOnline()); + } + }); + + // Log + _manager.log("Set Home for [" + clan.getName() + "] to " + UtilWorld.locToStrClean(loc) + " by [" + player + "]."); + } + + public void saveClan(final ClanInfo clan) + { + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.updateClan(clan.getId(), clan.getName(), clan.getDesc(), UtilWorld.locToStr(clan.getHome()), clan.isAdmin(), clan.getEnergy(), clan.getKills(), clan.getMurder(), clan.getDeaths(), clan.getWarWins(), clan.getWarLosses(), clan.getLastOnline()); + } + }); + } + + public void war(final ClanInfo clanA, final ClanInfo clanB, final int score, final Callback warCallback) + { + final Timestamp currentTime = new Timestamp(System.currentTimeMillis()); + final ClanWarData war = new ClanWarData(clanA.getName(), clanB.getName(), score, currentTime, currentTime, 0); + + // Memory + clanA.addWar(war); + clanB.addWar(war); + + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.addWar(clanA.getId(), clanB.getId(), score, currentTime); + + runSync(new Runnable() + { + @Override + public void run() + { + _manager.log("Initiator war for [" + clanA.getName() + "] against [" + clanB.getName() + "]."); + + if (warCallback != null) warCallback.run(war); + } + }); + } + }); + + } + + public void updateWar(final ClanInfo clanA, final ClanInfo clanB, final ClanWarData war, final Callback callback) + { + runAsync(new Runnable() + { + @Override + public void run() + { + final boolean ran = _repository.updateWar(clanA.getId(), clanB.getId(), war.getPoints(), war.getLastUpdated()); + runSync(new Runnable() + { + @Override + public void run() + { + if (callback != null) callback.run(ran); + } + }); + } + }); + } + + /* + * public void updateEnemy(ClanInfo clan, ClanInfo otherClan) { assert + * clan.getEnemyData() != null && otherClan.getEnemyData() != null; assert + * clan.getEnemyData().getEnemyName() == otherClan.getName() && + * otherClan.getEnemyData().getEnemyName() == clan.getName(); ClanInfo + * initiator = clan.getEnemyData().isInitiator() ? clan : otherClan; + * EnemyData iData = initiator.getEnemyData(); ClanInfo other = clan == + * initiator ? otherClan : clan; EnemyData oData = other.getEnemyData(); + * _repository.updateEnemy(initiator.getId(), other.getId(), + * iData.getClanAScore(), oData.getClanAScore(), iData.getKills(), + * oData.getKills()); //Log _manager.log("Updated Enemy Data for [" + + * clan.getName() + ", " + otherClan.getName() + "]"); } + */ + + public void updateGenerator(final ClanInfo clanInfo, final Callback callback) + { + TntGenerator generator = clanInfo.getGenerator(); + final String creator; + final int generatorStock; + + if (generator != null) + { + creator = generator.getBuyer().toString(); + generatorStock = generator.getStock(); + } + else + { + creator = ""; + generatorStock = 0; + } + + runAsync(new Runnable() + { + @Override + public void run() + { + final boolean ran = _repository.updateClanGenerator(clanInfo.getId(), creator, generatorStock); + runSync(new Runnable() + { + @Override + public void run() + { + if (callback != null) + { + callback.run(ran); + } + else + { + if (!ran) + { + System.out.println("Tnt Gen didn't save!"); + } + } + } + }); + } + }); + } + + public void updateEnergy(ClanInfo clan) + { + // Save + // TODO: query to only update energy? + _repository.updateClan(clan.getId(), clan.getName(), clan.getDesc(), UtilWorld.locToStr(clan.getHome()), clan.isAdmin(), clan.getEnergy(), clan.getKills(), clan.getMurder(), clan.getDeaths(), clan.getWarWins(), clan.getWarLosses(), clan.getLastOnline()); + + // Log + _manager.log("Updated Energy for [" + clan.getName() + "] to " + clan.getEnergy() + "."); + } + + public void safe(ClanTerritory claim, String player) + { + // Memory + claim.Safe = !claim.Safe; + + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.updateTerritoryClaim(claim.ClaimLocation, claim.Safe); + } + }); + + // Log + _manager.log("Safe Zone at [" + claim.ClaimLocation.toStoredString() + "] set to [" + claim.Safe + "] by [" + player + "]."); + } + + public void retrieveClan(final String clanName, final Callback callback) + { + runAsync(new Runnable() + { + @Override + public void run() + { + ClanToken clan = _repository.retrieveClan(clanName); + runSync(() -> callback.run(clan)); + } + }); + } + + public void clanExists(String clanName, Callback callback) + { + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.clanExists(clanName, new Callback() + { + @Override + public void run(Boolean data) + { + runSync(new Runnable() + { + @Override + public void run() + { + if (callback != null) callback.run(data); + } + }); + } + }); + } + }); + } + + public ClanRepository getRepository() + { + return _repository; + } + + private void runAsync(Runnable runnable) + { + _manager.runAsync(runnable); + } + + private void runSync(Runnable runnable) + { + _manager.runSync(runnable); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java new file mode 100644 index 00000000..8123f862 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java @@ -0,0 +1,297 @@ +package mineplex.game.clans.clans; + +import java.util.LinkedList; + +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World.Environment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; +import mineplex.game.clans.clans.event.PlayerEnterTerritoryEvent; +import mineplex.game.clans.clans.nether.NetherManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.ClanTerritory; + +public class ClansDisplay extends MiniPlugin +{ + private ClansManager _clansManager; + + public ClansDisplay(JavaPlugin plugin, ClansManager clans) + { + super("Clans Display", plugin); + + _clansManager = clans; + } + + @EventHandler + public void Update(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) return; + + for (Player cur : UtilServer.getPlayers()) + Update(cur); + } + + public void Update(Player player) + { + if (player.getWorld().getEnvironment() != Environment.NORMAL) return; + + ClientClan client = _clansManager.Get(player); + if (client == null) return; + + // Same Chunk + if (client.getTerritory().equals(UtilWorld.chunkToStr(player.getLocation().getChunk()))) return; + + // Update Territory + client.setTerritory(UtilWorld.chunkToStr(player.getLocation().getChunk())); + + // AutoClaim + if (client.isAutoClaim() && !(Managers.get(NetherManager.class).isInNether(player) || Managers.get(WorldEventManager.class).getRaidManager().isInRaid(player.getLocation()))) _clansManager.getClanAdmin().claim(player); + + // Map + String owner = "Wilderness"; + ClanInfo ownerClan = _clansManager.getClanUtility().getOwner(player.getLocation()); + if (ownerClan != null) owner = ownerClan.getName(); + + boolean safe = _clansManager.getClanUtility().isSafe(player); + + PlayerEnterTerritoryEvent event = new PlayerEnterTerritoryEvent(player, client.getOwner(), owner, safe, true); + + UtilServer.getServer().getPluginManager().callEvent(event); + + if (!client.isMapOn()) + { + boolean showChange = false; + + // Owner Change + if (!client.getOwner().equals(owner)) + { + client.setOwner(owner); + showChange = true; + } + + // Safe Change + if (safe != client.isSafe()) + { + client.setSafe(safe); + showChange = true; + } + + if (showChange) + { + if (event.willSendMessage()) displayOwner(player); + } + } + else + { + if (event.willSendMessage()) displayOwner(player); + + displayMap(player); + } + } + + public void displayOwner(Player player) + { + // Name + String ownerString = C.xWilderness + "Wilderness"; + + ClanTerritory claim = _clansManager.getClanUtility().getClaim(player.getLocation()); + if (claim != null) + { + // Relation + ClanRelation relation = _clansManager.getClanUtility().relPT(player, claim.ClaimLocation); + + // Name + ownerString = _clansManager.getClanUtility().mRel(relation, claim.Owner, false); + + // Trust + if (relation == ClanRelation.ALLY_TRUST) ownerString += " " + C.mBody + "(" + C.mElem + "Trusted" + C.mBody + ")"; + } + + if (_clansManager.getNetherManager().isInNether(player)) + { + ownerString = C.cClansNether + "The Nether"; + if (_clansManager.getClanUtility().isSafe(player.getLocation())) + { + ownerString = C.cClansNether + "Nether Spawn"; + } + } + + if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + ownerString = C.cDRed + "Raid World"; + } + +// if (_clansManager.getNetherManager().isInNether(player)) +// { +// _clansManager.message(player, "You are not allowed to claim territory in " + F.clansNether("The Nether") + "."); +// +// ownerString = C.cRed + "The Nether"; +// } + + UtilTextMiddle.display("", ownerString, 0, 25, 10, player); + UtilPlayer.message(player, F.main("Territory", ownerString)); + } + + public int width = 8; + public int height = 4; + + public void displayMap(Player player) + { + if (player.getWorld().getEnvironment().equals(Environment.NETHER)) return; + + // Get Local + LinkedList local = mLocalMap(player, player.getLocation().getChunk(), true); + + // Get Home + LinkedList home = null; + + if (player.getItemInHand().getType() == Material.MAP) + { + ClanInfo clan = _clansManager.getClanUtility().getClanByPlayer(player); + if (clan != null) if (clan.getHome() != null) home = mLocalMap(player, clan.getHome().getChunk(), false); + } + + // Display + if (home == null || local.size() != home.size()) + UtilPlayer.message(player, local); + + else + for (int i = 0; i < local.size(); i++) + UtilPlayer.message(player, local.get(i) + " " + home.get(i)); + + // Display legend for map symbols + UtilPlayer.message(player, C.xNone + "X: Current, #: Claimed, H: Home"); + UtilPlayer.message(player, C.xNone + "S: Safe, +: Admin, -: Unclaimed"); + } + + public LinkedList mLocalMap(Player player, Chunk chunk, boolean local) + { + if (chunk == null) return null; + + LinkedList localMap = new LinkedList(); + + for (int i = (chunk.getX() - height); i <= (chunk.getX() + height); i++) + { + String output = C.xNone + "<"; + + for (int j = (chunk.getZ() + width); j >= (chunk.getZ() - width); j--) + { + Chunk curChunk = player.getWorld().getChunkAt(i, j); + + // Count Players + int pCount = 0; + if (player.getItemInHand().getType() == Material.MAP) + { + for (Player cur : UtilServer.getPlayers()) + if (cur.getLocation().getChunk().toString().equals(curChunk.toString())) pCount++; + } + + // Get Data + ClanInfo curOwner = _clansManager.getClanUtility().getOwner(ClaimLocation.of(curChunk)); + ClanTerritory curClaim = _clansManager.getClanUtility().getClaim(ClaimLocation.of(curChunk)); + + // Add Icon + if (i == chunk.getX() && j == chunk.getZ()) + output += getMapIcon(_clansManager.getClanUtility().relPC(player, curOwner), curClaim, curOwner, curChunk, pCount, true, local); + else + output += getMapIcon(_clansManager.getClanUtility().relPC(player, curOwner), curClaim, curOwner, curChunk, pCount, false, local); + } + + output += ">"; + + // Send + localMap.add(output); + } + + return localMap; + } + + public String getMapIcon(ClanRelation relation, ClanTerritory claim, ClanInfo owner, Chunk chunk, int players, boolean mid, boolean local) + { + if (players > 9) players = 9; + + if (mid && local) + { + if (players > 0) + return "" + C.cWhite + players; + else + return "" + C.cWhite + "X"; + } + + if (owner == null || claim == null) + { + if (players > 0) + return "" + C.xNone + players; + else + return "" + C.xNone + "-"; + } + + if (claim.Safe) + { + if (players > 0) + return "" + C.xSafe + players; + else + return "" + C.xSafe + "S"; + } + + if (owner.isAdmin()) + { + if (players > 0) + return "" + C.xAdmin + players; + else + return "" + C.xAdmin + "+"; + } + + if (relation == ClanRelation.SELF) + { + if (players > 0) + return "" + C.xSelf + players; + else if (_clansManager.getClanUtility().isChunkHome(owner, chunk)) + return "" + C.xSelf + "H"; + else + return "" + C.xSelf + "#"; + } + + if (relation == ClanRelation.ALLY) + { + if (players > 0) + return "" + C.xAlly + players; + else if (_clansManager.getClanUtility().isChunkHome(owner, chunk)) + return "" + C.xAlly + "H"; + else + return "" + C.xAlly + "#"; + } + + if (relation == ClanRelation.ALLY_TRUST) + { + if (players > 0) + return "" + C.xdAlly + players; + else if (_clansManager.getClanUtility().isChunkHome(owner, chunk)) + return "" + C.xdAlly + "H"; + else + return "" + C.xdAlly + "#"; + } + + if (players > 0) + return "" + C.xEnemy + players; + else if (_clansManager.getClanUtility().isChunkHome(owner, chunk)) + return "" + C.xEnemy + "H"; + else + return "" + C.xEnemy + "#"; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java new file mode 100644 index 00000000..87b3ee6c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java @@ -0,0 +1,1065 @@ +package mineplex.game.clans.clans; + +import java.sql.Timestamp; +import java.util.Iterator; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World.Environment; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +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.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.enchantment.EnchantItemEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; +import mineplex.game.clans.clans.event.ClansWaterPlaceEvent; +import mineplex.game.clans.clans.siege.weapon.projectile.event.CraterExplodeEvent; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class ClansGame extends MiniPlugin +{ + public enum Perm implements Permission + { + DUPE_ALERT, + } + + private static final int CLICKS_TO_OPEN_TRAPPED = 10; + private ClansManager _clans; + + public ClansGame(JavaPlugin plugin, ClansManager clans) + { + super("Clans Game", plugin); + + _clans = clans; + setupSafes(); + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.TRAINEE.setPermission(Perm.DUPE_ALERT, true, true); + } + + private void setupSafes() + { + Iterator it = Bukkit.getServer().recipeIterator(); + while (it.hasNext()) + { + Recipe recipe = it.next(); + if (recipe != null && recipe.getResult().getType() == Material.TRAPPED_CHEST) + { + it.remove(); + } + } + + ShapedRecipe safe = new ShapedRecipe(new ItemBuilder(Material.TRAPPED_CHEST).setAmount(1).setTitle(C.cDGray + "Safe").build()) + .shape(new String[] {"III", "ICI", "III"}) + .setIngredient('I', Material.IRON_INGOT) + .setIngredient('C', Material.CHEST); + + Bukkit.addRecipe(safe); + } + + public static boolean isDupedFromClassShop(ItemStack item) + { + if (item == null || item.getType() == Material.AIR) + { + return false; + } + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) + { + return false; + } + String name = ChatColor.stripColor(item.getItemMeta().getDisplayName()).toUpperCase(); + if (name.contains("APPLY DEFAULT BUILD") || name.contains("APPLY BUILD") || name.contains("EDIT BUILD") || name.contains("DELETE BUILD")) + { + return true; + } + + return false; + } + + @EventHandler(ignoreCancelled = true) + public void openClanShop(PlayerInteractEvent event) + { + boolean hasItem = event.getPlayer().getItemInHand().getType() != Material.AIR; + + if (UtilEvent.isAction(event, ActionType.R_BLOCK) && event.getClickedBlock().getType() == Material.ENCHANTMENT_TABLE) + { + if (!event.getPlayer().isSneaking() || !hasItem) + { + if (Recharge.Instance.use(event.getPlayer(), "Open Skill Table GUI", 1000, false, false)) + { + runSyncLater(() -> + { + if (event.getPlayer().isDead() || !event.getPlayer().isOnline() || !event.getPlayer().isValid()) + { + return; + } + if (UtilMath.offsetSquared(event.getClickedBlock().getLocation(), event.getPlayer().getLocation()) > 36) + { + return; + } + _clans.getClassShop().attemptShopOpen(event.getPlayer()); + }, 10); + } + event.setCancelled(true); + } + } + } + + @EventHandler + public void onEnchant(EnchantItemEvent event) + { + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW) + public void BlockBurn(BlockBurnEvent event) + { + if (_clans.getClanUtility().isBorderlands(event.getBlock().getLocation())) event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW) + public void BlockSpread(BlockIgniteEvent event) + { + if (event.getCause() == IgniteCause.SPREAD) if (_clans.getClanUtility().isBorderlands(event.getBlock().getLocation())) event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void BlockPlace(BlockPlaceEvent event) + { + Player player = event.getPlayer(); + + if (isDupedFromClassShop(event.getItemInHand())) + { + event.setCancelled(true); + for (Player p : Bukkit.getOnlinePlayers()) + { + if (ClansManager.getInstance().getClientManager().Get(p).hasPermission(Perm.DUPE_ALERT)) + { + UtilPlayer.message(p, F.elem("[" + C.cRedB + "!" + C.cGray + "] ") + player.getName() + " just tried to use a duped item/block!"); + } + } + final int slot = player.getInventory().getHeldItemSlot(); + ClansManager.getInstance().runSyncLater(() -> + { + player.getInventory().setItem(slot, new ItemStack(Material.AIR)); + player.updateInventory(); + }, 1L); + + return; + } + + if (_clans.getClanUtility().getAccess(player, event.getBlock().getLocation()) == ClanRelation.SELF) + { + if (_clans.getClanUtility().getOwner(event.getBlock().getLocation()) != null) + { + if (event.getBlock().getType() == Material.HOPPER && (event.getBlock().getRelative(BlockFace.UP).getType() == Material.CHEST || event.getBlock().getRelative(BlockFace.UP).getType() == Material.TRAPPED_CHEST)) + { + if (_clans.getClanUtility().getRole(player) == ClanRole.RECRUIT) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "Recruits cannot siphon items out of chests with a hopper!")); + event.setCancelled(true); + } + } + } + + return; + } + + final Block block = event.getBlock(); + + if (block.getType() != Material.LADDER) + { + return; + } + + if (_clans.getWorldEvent().isInEvent(block.getLocation().add(0.5, 0.5, 0.5), false) || block.equals(player.getLocation().getBlock())) + { + player.sendMessage("Cancelled dodgy ladder placement"); + event.setCancelled(true); + } + else + { + _clans.runSyncLater(() -> _clans.getBlockRestore().add(block, 65, block.getData(), 0, (byte) 0, 30000), 0); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void teleport(PlayerTeleportEvent event) + { + if (event.getCause() == TeleportCause.UNKNOWN) + { + UtilPlayer.closeInventoryIfOpen(event.getPlayer()); + } + } + + @EventHandler + public void onFishHookEvent(PlayerFishEvent event) + { + if (event.getCaught() instanceof Player) + { + Player defender = (Player) event.getCaught(); + Player attacker = event.getPlayer(); + + if (!_clans.getClanUtility().canHurt(defender, attacker)) + { + event.setCancelled(true); + ClanRelation rel = _clans.getRelation(defender, attacker); + UtilPlayer.message(attacker, F.main("Clans", "You cannot harm " + _clans.getClanUtility().mRel(rel, defender.getName(), false) + ".")); + } + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onPlayerFillBucket(PlayerBucketFillEvent event) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot fill buckets!")); + _clans.runSyncLater(() -> + { + event.getPlayer().updateInventory(); + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); + event.getPlayer().sendBlockChange(block.getLocation(), block.getType(), block.getData()); + }, 1L); + } + + @EventHandler + public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) + { + Material bucket = event.getBucket(); + + if (bucket == Material.LAVA_BUCKET || bucket == Material.WATER_BUCKET) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot empty buckets!")); + } + } + + @EventHandler + public final void onFoodLevelChangeEvent(FoodLevelChangeEvent event) + { + ((Player) event.getEntity()).setSaturation(3.8F); // While not entirely + // accurate, this is + // a pretty good + // guess at original + // food level + // changes + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void BlockBreak(BlockBreakEvent event) + { + if (event.getPlayer().getWorld().getEnvironment() != Environment.NORMAL || event.getPlayer().getGameMode() == GameMode.CREATIVE) return; + + String mimic = _clans.Get(event.getPlayer()).getMimic(); + + if (mimic.length() != 0) + { + if (_clans.getClanUtility().searchClanPlayer(event.getPlayer(), mimic, false) != null) + mimic = C.cGray + " You are currently mimicing " + C.cGold + mimic; + else + mimic = ""; + } + + // Borderlands + if (_clans.getClanUtility().isBorderlands(event.getBlock().getLocation()) && event.getPlayer().getGameMode() != GameMode.CREATIVE) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You can not break blocks in " + F.elem("Borderlands") + ".")); + return; + } + + if (_clans.getClanBlocks().canBreak(event.getBlock().getTypeId())) return; + + if (_clans.getClanUtility().getAccess(event.getPlayer(), event.getBlock().getLocation()) == ClanRelation.SELF) + { + // Disallow Shops + if (event.getBlock().getType() == Material.ENDER_CHEST || event.getBlock().getType() == Material.ENCHANTMENT_TABLE) if (_clans.getClanUtility().isSafe(event.getBlock().getLocation())) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You can not break blocks in " + _clans.getClanUtility().getOwnerStringRel(event.getBlock().getLocation(), event.getPlayer()) + C.mBody + "'s Territory.")); + } + + // Disallow Recruit Chest + if (_clans.getClanUtility().isClaimed(event.getBlock().getLocation())) + { + if (event.getBlock().getType() == Material.CHEST || event.getBlock().getType() == Material.TRAPPED_CHEST) + { + if (_clans.getClanUtility().getRole(event.getPlayer()) == ClanRole.RECRUIT) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(event.getPlayer(), F.main("Clans", "Clan Recruits cannot break " + F.elem(ItemStackFactory.Instance.GetName(event.getBlock(), true)) + ".")); + } + } + } + + // Allow + return; + } + + if (_clans.getClan(event.getPlayer()) != null && _clans.getClanUtility().isClaimed(event.getBlock().getLocation())) + { + if (_clans.getWarManager().isBeingBesiegedBy(_clans.getClanUtility().getOwner(event.getBlock().getLocation()), _clans.getClan(event.getPlayer()))) + { + if (event.getBlock().getType() == Material.CHEST || event.getBlock().getType() == Material.DISPENSER || event.getBlock().getType() == Material.DROPPER || event.getBlock().getType() == Material.FURNACE || event.getBlock().getType() == Material.BURNING_FURNACE) + { + return; + } + if (event.getBlock().getType() == Material.TRAPPED_CHEST) + { + if (Recharge.Instance.use(event.getPlayer(), "Chest Crack", 1000, true, false)) + { + int clicksRemain = CLICKS_TO_OPEN_TRAPPED; + if (event.getBlock().hasMetadata("CLICKS - " + event.getPlayer().getName())) + { + clicksRemain = event.getBlock().getMetadata("CLICKS - " + event.getPlayer().getName()).get(0).asInt(); + event.getBlock().removeMetadata("CLICKS - " + event.getPlayer().getName(), _clans.getPlugin()); + } + + clicksRemain--; + if (clicksRemain > 0) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You must try to break that chest " + clicksRemain + " more times before it will yield!")); + event.getBlock().setMetadata("CLICKS - " + event.getPlayer().getName(), new FixedMetadataValue(_clans.getPlugin(), clicksRemain)); + } + else + { + return; + } + } + + event.setCancelled(true); + return; + } + } + } + + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You can not break blocks in " + _clans.getClanUtility().getOwnerStringRel(event.getBlock().getLocation(), event.getPlayer()) + C.mBody + "'s Territory." + mimic)); + } + + @EventHandler + public void respawn(PlayerRespawnEvent event) + { + _clans.getItemMapManager().setMap(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.LOW) + public void Damage(CustomDamageEvent event) + { + if (event.IsCancelled()) return; + + Player damagee = event.GetDamageePlayer(); + if (damagee == null) return; + + Player damager = event.GetDamagerPlayer(true); + if (damager == null) return; + + if (!_clans.getClanUtility().canHurt(damagee, damager)) + { + // Cancel + event.SetCancelled("Clans Ally"); + + // Inform + if (damager != null) + { + ClanRelation rel = _clans.getRelation(damagee, damager); + UtilPlayer.message(damager, F.main("Clans", "You cannot harm " + _clans.getClanUtility().mRel(rel, damagee.getName(), false) + ".")); + } + } + } + + // Block Interact and Placement + public void Interact(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (player.getWorld().getEnvironment() != Environment.NORMAL) return; + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.LEFT_CLICK_BLOCK) return; + + // Block Interaction + Location loc = event.getClickedBlock().getRelative(event.getBlockFace()).getLocation(); + if (UtilBlock.usable(event.getClickedBlock())) loc = event.getClickedBlock().getLocation(); + + if (_clans.getClan(player) != null && _clans.getClanUtility().isClaimed(loc)) + { + if (_clans.getWarManager().isBeingBesiegedBy(_clans.getClanUtility().getOwner(loc), _clans.getClan(player))) + { + if (loc.getBlock().getType() == Material.CHEST || loc.getBlock().getType() == Material.DISPENSER || loc.getBlock().getType() == Material.DROPPER || loc.getBlock().getType() == Material.FURNACE || loc.getBlock().getType() == Material.BURNING_FURNACE) + { + return; + } + if (loc.getBlock().getType() == Material.TRAPPED_CHEST) + { + if (Recharge.Instance.use(player, "Chest Crack", 1000, true, false)) + { + int clicksRemain = CLICKS_TO_OPEN_TRAPPED; + if (loc.getBlock().hasMetadata("CLICKS - " + player.getName())) + { + clicksRemain = loc.getBlock().getMetadata("CLICKS - " + player.getName()).get(0).asInt(); + loc.getBlock().removeMetadata("CLICKS - " + player.getName(), _clans.getPlugin()); + } + + clicksRemain--; + if (clicksRemain > 0) + { + UtilPlayer.message(player, F.main("Clans", "You must try to open that chest " + clicksRemain + " more times before it will yield!")); + loc.getBlock().setMetadata("CLICKS - " + player.getName(), new FixedMetadataValue(_clans.getPlugin(), clicksRemain)); + } + else + { + return; + } + } + + event.setCancelled(true); + return; + } + } + } + + // Borderlands + if (player.getGameMode() != GameMode.CREATIVE && player.getItemInHand() != null && _clans.getClanBlocks().denyUsePlace(player.getItemInHand().getTypeId()) && _clans.getClanUtility().isBorderlands(event.getClickedBlock().getLocation())) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "You cannot place blocks in " + F.elem("Borderlands") + ".")); + return; + } + + // Banners/String/Heads + if (player.getGameMode() != GameMode.CREATIVE && player.getItemInHand() != null) + { + if (player.getItemInHand().getType() == Material.BANNER || player.getItemInHand().getType() == Material.STRING + || player.getItemInHand().getType() == Material.SKULL_ITEM) + { + Location destLocation = event.getClickedBlock().getRelative(event.getBlockFace()).getLocation(); + ClanTerritory territory = _clans.getClanUtility().getClaim(destLocation); + if (territory != null) + { + if (territory.Owner.equals("Shops") || territory.Owner.equals("Fields") || territory.Owner.equals("Spawn") || territory.Owner.equals("Borderlands")) { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "You cannot place that in " + F.elem(_clans.getClanUtility().getOwnerStringRel(destLocation, player)) + ".")); + return; + } + } + } + } + + ClanRelation access = _clans.getClanUtility().getAccess(player, loc); + ClanInfo clan = _clans.getClan(player); + ClanInfo mimicClan = _clans.getClanAdmin().getMimic(player, false); + ClanInfo blockClan = _clans.getClanUtility().getClaim(loc) == null ? null : _clans.getClan(_clans.getClanUtility().getClaim(loc).Owner); + if (blockClan != null && blockClan.equals(mimicClan)) access = ClanRelation.SELF; + + // Doors, chests, & furnaces + if (blockClan != null && (!blockClan.equals(clan) && !blockClan.equals(mimicClan)) && (event.getAction() == Action.RIGHT_CLICK_BLOCK && (loc.getBlock().getType().name().contains("DOOR") || loc.getBlock().getType().name().contains("GATE") || UtilItem.doesHaveGUI(loc.getBlock().getType())))) + { + UtilPlayer.message(player, F.main("Clans", "You are not allowed to use that here.")); + event.setCancelled(true); + return; + } + + // Hoe Return + if (access != ClanRelation.SELF && !UtilBlock.usable(event.getClickedBlock())) + { + if (UtilGear.isHoe(player.getItemInHand())) + { + event.setCancelled(true); + return; + } + } + + // Full Access + if (access == ClanRelation.SELF) + { + // Recruits cannot open Chests // IN OWN CLAIMED LAND + if (event.getClickedBlock().getTypeId() == 54 && _clans.getClanUtility().getOwner(loc) != null) + { + if (_clans.getClanUtility().getRole(player) == ClanRole.RECRUIT) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "Clan Recruits cannot access " + F.elem(ItemStackFactory.Instance.GetName(event.getClickedBlock(), true)) + ".")); + } + } + + // Wilderness Adjacent + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && !UtilBlock.usable(event.getClickedBlock()) && player.getItemInHand() != null && _clans.getClanBlocks().denyUsePlace(player.getItemInHand().getTypeId()) && !_clans.getClanUtility().isClaimed(loc)) + { + + String enemy = null; + boolean self = false; + + for (int x = -1; x <= 1; x++) + for (int z = -1; z <= 1; z++) + { + if (self) continue; + + if (x != 0 && z != 0 || x == 0 && z == 0) continue; + + Location sideLoc = new Location(loc.getWorld(), loc.getX() + x, loc.getY(), loc.getZ() + z); + + if (_clans.getClanUtility().isSelf(player, sideLoc)) self = true; + + if (enemy != null) continue; + + if (_clans.getClanUtility().getAccess(player, sideLoc) != ClanRelation.SELF) enemy = _clans.getClanUtility().getOwnerStringRel(new Location(loc.getWorld(), loc.getX() + x, loc.getY(), loc.getZ() + z), player); + } + + if (enemy != null && !self) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "You cannot place blocks next to " + enemy + ".")); + + return; + } + } + + return; + } + + String mimic = _clans.Get(player).getMimic(); + + if (mimic.length() != 0) + { + if (_clans.getClanUtility().searchClanPlayer(player, mimic, false) != null) + mimic = C.cGray + " You are currently mimicing " + C.cGold + mimic; + else + mimic = ""; + } + + // Deny Interaction + if (_clans.getClanBlocks().denyInteract(event.getClickedBlock().getTypeId())) + { + // Block Action + if (access == ClanRelation.NEUTRAL) + { + Location home = event.getClickedBlock() == null ? null : _clans.getClanUtility().getClanByClanName(_clans.getClanUtility().getClaim(event.getClickedBlock().getLocation()).Owner).getHome(); + + // Allow Field Chest + if (event.getClickedBlock().getTypeId() == 54) + { + if (_clans.getClanUtility().isSpecial(event.getClickedBlock().getLocation(), "Fields")) + { + return; + } + } + + // Allow Clan's Home + if (home != null && event.getClickedBlock().getLocation().distance(home) <= 2 && event.getClickedBlock().getType().equals(Material.BED_BLOCK)) + { + return; + } + + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "You cannot use items in " + _clans.getClanUtility().getOwnerStringRel(event.getClickedBlock().getLocation(), player) + C.mBody + "'s Territory." + mimic)); + + return; + } + // Block is not Trust Allowed + else if (!_clans.getClanBlocks().allowInteract(event.getClickedBlock().getTypeId()) || access != ClanRelation.ALLY_TRUST) + { + Location home = event.getClickedBlock() == null ? null : _clans.getClanUtility().getClanByClanName(_clans.getClanUtility().getClaim(event.getClickedBlock().getLocation()).Owner).getHome(); + + // Allow Clan's Home + if (home != null && event.getClickedBlock().getLocation().distance(home) <= 2 && event.getClickedBlock().getType().equals(Material.BED_BLOCK)) + { + return; + } + + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "You cannot use items in " + _clans.getClanUtility().getOwnerStringRel(event.getClickedBlock().getLocation(), player) + C.mBody + "'s Territory." + mimic)); + + return; + } + } + + // Block Placement + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) + { + if (player.getItemInHand().getType() != Material.AIR) + { + if (player.getGameMode() != GameMode.CREATIVE && _clans.getClanBlocks().denyUsePlace(player.getItemInHand().getTypeId())) + { + // Disallow + event.setCancelled(true); + + // Inform + UtilPlayer.message(player, F.main("Clans", "You cannot place blocks in " + _clans.getClanUtility().getOwnerStringRel(event.getClickedBlock().getRelative(event.getBlockFace()).getLocation(), player) + C.mBody + "'s Territory." + mimic)); + + return; + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void doorPlaced(BlockPlaceEvent event) + { + if (event.getBlockPlaced().getType().equals(Material.ACACIA_DOOR) + || event.getBlockPlaced().getType().equals(Material.WOODEN_DOOR) + || event.getBlockPlaced().getType().equals(Material.BIRCH_DOOR) + || event.getBlockPlaced().getType().equals(Material.DARK_OAK_DOOR) + || event.getBlockPlaced().getType().equals(Material.JUNGLE_DOOR) + || event.getBlockPlaced().getType().equals(Material.SPRUCE_DOOR) + || event.getBlockPlaced().getType().equals(Material.WOOD_DOOR) + || event.getBlockPlaced().getType().equals(Material.IRON_DOOR_BLOCK)) + { + ClanTerritory claim = _clans.getClanUtility().getClaim(event.getBlockPlaced().getLocation()); + + if (claim != null && (claim.Owner.equals("Spawn") || claim.Owner.equals("Shops") || claim.Owner.equals("Fields") || _clans.getClanUtility().getAccess(event.getPlayer(), event.getBlockPlaced().getLocation()) != ClanRelation.SELF)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void Piston(BlockPistonExtendEvent event) + { + ClanInfo pistonClan = _clans.getClanUtility().getOwner(event.getBlock().getLocation()); + + Block push = event.getBlock(); + for (int i = 0; i < 13; i++) + { + push = push.getRelative(event.getDirection()); + + Block front = push.getRelative(event.getDirection()).getRelative(event.getDirection()); + + if (push.getType() == Material.AIR) return; + + ClanInfo pushClan = _clans.getClanUtility().getOwner(front.getLocation()); + + if (pushClan == null) continue; + + if (pushClan.isAdmin()) continue; + + if (pistonClan == null) + { + push.getWorld().playEffect(push.getLocation(), Effect.STEP_SOUND, push.getTypeId()); + event.setCancelled(true); + return; + } + + if (pistonClan.equals(pushClan)) continue; + + push.getWorld().playEffect(push.getLocation(), Effect.STEP_SOUND, push.getTypeId()); + event.setCancelled(true); + return; + } + } + + @EventHandler + public void Quit(PlayerQuitEvent event) + { + ClanInfo clan = _clans.getClanUtility().getClanByPlayer(event.getPlayer()); + if (clan == null) return; + + clan.setLastOnline(new Timestamp(System.currentTimeMillis())); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void Explosion(EntityExplodeEvent event) + { + try + { + if (event.getEntityType() != EntityType.PRIMED_TNT && event.getEntityType() != EntityType.MINECART_TNT) return; + } + catch (Exception e) + { + return; + } + + ClanInfo clan = _clans.getClanUtility().getOwner(event.getEntity().getLocation()); + if (clan == null) return; + + clan.inform(C.cRed + "Your Territory is under attack!", null); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Explosion(CraterExplodeEvent event) + { + for (Block block : event.getBlocks()) + { + ClanInfo clan = _clans.getClanUtility().getOwner(block.getLocation()); + if (clan == null) + { + return; + } + + if (Recharge.Instance.use(event.getShooter(), "TNT TERRITORY ALERT", 1000, false, false)) + { + clan.inform(C.cRed + "Your Territory is under attack!", null); + } + } + } + + @EventHandler + public void onClanHomeInteract(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.L_BLOCK) && !UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + return; + } + + ClanInfo clan = _clans.getClan(event.getPlayer()); + + Block block = event.getClickedBlock(); + + if (UtilEvent.isAction(event, ActionType.R_BLOCK) && block.getType() == Material.BED_BLOCK) + { + event.setCancelled(true); + return; + } + + Player player = event.getPlayer(); + + if (clan == null) + { + for (String otherClanName : _clans.getClanNameSet()) + { + boolean done = false; + ClanInfo otherClan = _clans.getClan(otherClanName); + + if (otherClan.getHome() == null) + { + return; + } + + if (!(UtilMath.offset(block.getLocation(), otherClan.getHome()) < 3)) + { + return; + } + + for (int x = -2; x < 2; x++) + { + for (int z = -2; z < 2; z++) + { + Block otherBlock = event.getClickedBlock().getLocation().add(x, 0, z).getBlock(); + if (otherBlock.getType().equals(Material.BED_BLOCK)) + { + if (UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + event.setCancelled(true); + done = true; + break; + } + } + } + + if (done) + { + break; + } + } + + if (done) + { + break; + } + } + + return; + } + + if (clan.getHome() == null) + { + return; + } + + if (!(UtilMath.offset(block.getLocation(), clan.getHome()) < 3)) + { + return; + } + + for (int x = -2; x < 2; x++) + { + for (int z = -2; z < 2; z++) + { + Block otherBlock = event.getClickedBlock().getLocation().clone().add(x, 0, z).getBlock(); + if (otherBlock.getType().equals(Material.BED_BLOCK)) + { + if (UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + event.setCancelled(true); + break; + } + + if (clan.getMembers().get(player.getUniqueId()).getRole() == ClanRole.LEADER || clan.getMembers().get(player.getUniqueId()).getRole() == ClanRole.ADMIN) + { + break; + } + else + { + UtilPlayer.message(player, F.main("Clans", "Only the Clan Leader and Admins can manage the Clan Home.")); + break; + } + } + } + } + } + + @EventHandler + public void onPlaceBed(BlockPlaceEvent event) + { + if (event.getItemInHand().getType().equals(Material.BED) || event.getItemInHand().getType().equals(Material.BED_BLOCK)) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot manually place beds, to set your clan home, type " + F.elem("/c sethome") + ".")); + event.setCancelled(true); + } + } + + @EventHandler + public void onClanHomeDestroyed(BlockBreakEvent event) + { + ClanInfo userClan = _clans.getClan(event.getPlayer()); + + Block block = event.getBlock(); + Player player = event.getPlayer(); + + ClanInfo blockClan = null; + ClanTerritory claim = _clans.getClanUtility().getClaim(block.getLocation()); + + if (claim != null) + { + if (_clans.getBlacklist().allowed(claim.Owner)) + { + blockClan = _clans.getClan(claim.Owner); + } + } + + if (blockClan == null) + { + return; + } + + if (blockClan.getHome() == null) + { + return; + } + + if (UtilMath.offset(block.getLocation(), blockClan.getHome()) > 2) + { + return; + } + + if (!block.getType().equals(Material.BED_BLOCK)) + { + return; + } + + if (!blockClan.equals(userClan)) + { + if (userClan != null && blockClan.isAlly(userClan)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot remove an Ally's Clan Home.")); + } + else + { + UtilPlayer.message(player, F.main("Clans", "You have destroyed " + F.elem(blockClan.getName()) + "'s Clan Home!")); + + UtilBlock.deleteBed(blockClan.getHome()); + + blockClan.setHome(null); + } + + return; + } + + if (userClan.getMembers().get(player.getUniqueId()).getRole() == ClanRole.LEADER || userClan.getMembers().get(player.getUniqueId()).getRole() == ClanRole.ADMIN) + { + event.setCancelled(true); + + UtilBlock.deleteBed(blockClan.getHome()); + + blockClan.setHome(null); + UtilPlayer.message(player, F.main("Clans", "You have removed your Clan Home.")); + } + else + { + event.setCancelled(true); + UtilPlayer.message(player, F.main("Clans", "Only the Clan Leader and Admins can remove the Clan Home.")); + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.FAST) + { + for (Player player : Bukkit.getOnlinePlayers()) + { + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + + UtilInv.removeAll(player, Material.BED, (byte) 0); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPickupSafe(PlayerPickupItemEvent event) + { + Item item = event.getItem(); + ItemStack stack = item.getItemStack(); + if (stack.getType() == Material.TRAPPED_CHEST) + { + event.setCancelled(true); + item.remove(); + UtilInv.insert(event.getPlayer(), new ItemBuilder(Material.TRAPPED_CHEST).setAmount(stack.getAmount()).setTitle(C.cDGray + "Safe").build()); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPickupSafe(InventoryPickupItemEvent event) + { + Item item = event.getItem(); + ItemStack stack = item.getItemStack(); + if (stack.getType() == Material.TRAPPED_CHEST) + { + event.setCancelled(true); + item.remove(); + event.getInventory().addItem(new ItemBuilder(Material.TRAPPED_CHEST).setAmount(stack.getAmount()).setTitle(C.cDGray + "Safe").build()); + } + } + + @EventHandler(ignoreCancelled=true) + public void onBlockDispense(BlockDispenseEvent event) + { + if (event.getItem().getType() == Material.WATER_BUCKET || event.getItem().getType() == Material.LAVA_BUCKET || event.getItem().getType() == Material.BUCKET) + { + event.setCancelled(true); + } + } + + @EventHandler + public void noMonsterLava(BlockFromToEvent event) + { + Block block = event.getBlock(); + if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA || block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) + { + Block next = event.getToBlock(); + for (BlockFace bf : BlockFace.values()) + { + if (!next.getRelative(bf).equals(block)) + { + if (block.getType().toString().contains("LAVA")) + { + if (next.getRelative(bf).getType().toString().contains("WATER")) + { + event.setCancelled(true); + } + } + if (block.getType().toString().contains("WATER")) + { + if (next.getRelative(bf).getType().toString().contains("LAVA")) + { + event.setCancelled(true); + } + } + } + } + } + } + + @EventHandler + public void onUseWater(ClansWaterPlaceEvent event) + { + for (BlockFace bf : BlockFace.values()) + { + if (event.getBlock().getRelative(bf).getType().toString().contains("LAVA")) + { + event.setCancelled(true); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java new file mode 100644 index 00000000..0f696202 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -0,0 +1,1578 @@ +package mineplex.game.clans.clans; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.event.vehicle.VehicleEnterEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import com.mineplex.clansqueue.common.ClansQueueMessenger; +import com.mineplex.clansqueue.common.QueueConstant; +import com.mineplex.clansqueue.common.messages.ClansServerStatusMessage; +import com.mineplex.clansqueue.common.messages.ServerOfflineMessage; +import com.mineplex.clansqueue.common.messages.ServerOnlineMessage; + +import mineplex.core.Managers; +import mineplex.core.MiniClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.chat.Chat; +import mineplex.core.chat.ChatChannel; +import mineplex.core.chat.event.FormatPlayerChatEvent; +import mineplex.core.common.Pair; +import mineplex.core.common.events.PlayerMessageEvent; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.communities.CommunityManager; +import mineplex.core.creature.Creature; +import mineplex.core.creature.event.CreatureSpawnCustomEvent; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.elo.EloManager; +import mineplex.core.energy.Energy; +import mineplex.core.explosion.Explosion; +import mineplex.core.hologram.Hologram; +import mineplex.core.hologram.HologramManager; +import mineplex.core.incognito.IncognitoManager; +import mineplex.core.incognito.events.IncognitoStatusChangeEvent; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.menu.MenuManager; +import mineplex.core.movement.Movement; +import mineplex.core.npc.NpcManager; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.personalServer.PersonalServerManager; +import mineplex.core.portal.GenericServer; +import mineplex.core.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.core.preferences.PreferencesManager; +import mineplex.core.projectile.ProjectileManager; +import mineplex.core.punish.Punish; +import mineplex.core.punish.PunishClient; +import mineplex.core.recharge.Recharge; +import mineplex.core.stats.StatsManager; +import mineplex.core.task.TaskManager; +import mineplex.core.teleport.Teleport; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; +import mineplex.game.clans.clans.amplifiers.AmplifierManager; +import mineplex.game.clans.clans.antiafk.AfkManager; +import mineplex.game.clans.clans.banners.BannerManager; +import mineplex.game.clans.clans.boxes.BoxManager; +import mineplex.game.clans.clans.cash.CashShopManager; +import mineplex.game.clans.clans.commands.ClansAllyChatCommand; +import mineplex.game.clans.clans.commands.ClansChatCommand; +import mineplex.game.clans.clans.commands.ClansCommand; +import mineplex.game.clans.clans.commands.KillCommand; +import mineplex.game.clans.clans.commands.MapCommand; +import mineplex.game.clans.clans.commands.RegionsCommand; +import mineplex.game.clans.clans.commands.SpeedCommand; +import mineplex.game.clans.clans.data.PlayerClan; +import mineplex.game.clans.clans.event.ClansPlayerDeathEvent; +import mineplex.game.clans.clans.gui.ClanShop; +import mineplex.game.clans.clans.invsee.InvseeManager; +import mineplex.game.clans.clans.loot.LootManager; +import mineplex.game.clans.clans.map.ItemMapManager; +import mineplex.game.clans.clans.moderation.antialt.AltManager; +import mineplex.game.clans.clans.mounts.MountManager; +import mineplex.game.clans.clans.nameblacklist.ClansBlacklist; +import mineplex.game.clans.clans.nether.NetherManager; +import mineplex.game.clans.clans.observer.ObserverManager; +import mineplex.game.clans.clans.playtime.Playtime; +import mineplex.game.clans.clans.potato.PotatoManager; +import mineplex.game.clans.clans.pvptimer.PvPTimerManager; +import mineplex.game.clans.clans.redis.ClanDeleteCommandHandler; +import mineplex.game.clans.clans.redis.ClanLoadCommandHandler; +import mineplex.game.clans.clans.regions.ClansRegions; +import mineplex.game.clans.clans.scoreboard.ClansScoreboardManager; +import mineplex.game.clans.clans.siege.SiegeManager; +import mineplex.game.clans.clans.supplydrop.SupplyDropManager; +import mineplex.game.clans.clans.tntgenerator.TntGeneratorManager; +import mineplex.game.clans.clans.war.WarManager; +import mineplex.game.clans.clans.warpoints.WarPointEvasion; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.ClanDeleteCommand; +import mineplex.game.clans.core.ClanLoadCommand; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.core.repository.tokens.ClanMemberToken; +import mineplex.game.clans.core.repository.tokens.ClanTerritoryToken; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.fields.Field; +import mineplex.game.clans.gameplay.Gameplay; +import mineplex.game.clans.gameplay.HiddenChestManager; +import mineplex.game.clans.gameplay.safelog.SafeLog; +import mineplex.game.clans.gameplay.safelog.npc.NPCManager; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.restart.RestartManager; +import mineplex.game.clans.spawn.Spawn; +import mineplex.game.clans.tutorial.TutorialManager; +import mineplex.minecraft.game.classcombat.Class.ClassManager; +import mineplex.minecraft.game.classcombat.Class.ClientClass; +import mineplex.minecraft.game.classcombat.Class.IPvpClass; +import mineplex.minecraft.game.classcombat.Class.repository.token.CustomBuildToken; +import mineplex.minecraft.game.classcombat.Condition.SkillConditionManager; +import mineplex.minecraft.game.classcombat.Skill.Assassin.Blink; +import mineplex.minecraft.game.classcombat.Skill.Assassin.Flash; +import mineplex.minecraft.game.classcombat.Skill.Mage.events.FissureModifyBlockEvent; +import mineplex.minecraft.game.classcombat.Skill.SkillFactory; +import mineplex.minecraft.game.classcombat.item.ItemFactory; +import mineplex.minecraft.game.classcombat.shop.ClassCombatShop; +import mineplex.minecraft.game.classcombat.shop.ClassShopManager; +import mineplex.minecraft.game.core.IRelation; +import mineplex.minecraft.game.core.combat.CombatManager; +import mineplex.minecraft.game.core.condition.Condition; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.minecraft.game.core.damage.DamageManager; +import mineplex.minecraft.game.core.fire.Fire; +import mineplex.minecraft.game.core.mechanics.Weapon; +import mineplex.serverdata.commands.ServerCommandManager; + +public class ClansManager extends MiniClientPlugin implements IRelation +{ + public enum Perm implements Permission + { + ALLY_CHAT_COMMAND, + CLAN_CHAT_COMMAND, + CLANS_COMMAND, + SUICIDE_COMMAND, + MAP_COMMAND, + REGION_CLEAR_COMMAND, + SPEED_COMMAND, + FORCE_JOIN_COMMAND, + AUTO_OP, + PREFIX_SHOWN, + JOIN_FULL, + } + + public static final int CLAIMABLE_RADIUS = 800; + public static final int WORLD_RADIUS = 1200; + private static final TimeZone TIME_ZONE = TimeZone.getDefault(); + private static ClansManager _instance; + + public static ClansManager getInstance() + { + return _instance; + } + + private String _serverName; + + private CoreClientManager _clientManager; + private CombatManager _combatManager; + private ClansUtility _clanUtility; + private ClansScoreboardManager _scoreboard; + private ClansDataAccessLayer _clanDataAccess; + private ClansDisplay _clanDisplay; + private ClansAdmin _clanAdmin; + private ClansGame _clanGame; + private ClansBlocks _clanBlocks; + private ClansRegions _clanRegions; + private BlockRestore _blockRestore; + private Teleport _teleport; + private ConditionManager _condition; + private ClassCombatShop _classShop; + private HologramManager _hologramManager; + private GearManager _gearManager; + private LootManager _lootManager; + private DonationManager _donationManager; + private InventoryManager _inventoryManager; + private NetherManager _netherManager; + private DamageManager _damageManager; + private SiegeManager _siegeManager; + private IncognitoManager _incognitoManager; + + private ClansBlacklist _blacklist; + + private Playtime _playTracker; + + private TutorialManager _tutorial; + + private ClassManager _classManager; + private BannerManager _bannerManager; + private AmplifierManager _amplifierManager; + private RestartManager _restartManager; + + private SafeLog _safeLog; + + public ClassManager getClassManager() + { + return _classManager; + } + + private WarManager _warManager; + private ProjectileManager _projectileManager; + private WorldEventManager _worldEvent; + private Chat _chat; + private ItemMapManager _itemMapManager; + private DisguiseManager _disguiseManager; + private NpcManager _npcManager; + private Explosion _explosion; + private GoldManager _goldManager; + private WarPointEvasion _warPointEvasion; + private ObserverManager _observerManager; + private Punish _punish; + private TaskManager _taskManager; + private PvPTimerManager _timerManager = require(PvPTimerManager.class); + + private int _inviteExpire = 2; + private int _nameMin = 3; + private int _nameMax = 10; + private long _reclaimTime = 1800000; + private long _onlineTime = 1200000; + + // Command Shop + private ClanShop _clanShop; + + // Clans + private NautHashMap _clanMap = new NautHashMap(); + // private NautHashMap _clanMemberNameMap = new + // NautHashMap(); + private NautHashMap _clanMemberUuidMap = new NautHashMap(); + private NautHashMap> _clanMemberLeftMap = new NautHashMap<>(); + private NautHashMap _claimMap = new NautHashMap<>(); + private NautHashMap _unclaimMap = new NautHashMap<>(); + + public String UserDataDir = UtilServer.getServer().getWorlds().get(0).getWorldFolder().getPath() + File.separator + ".." + File.separator + "CLANS_USER_DATA" + File.separator; + + private PacketHandler _packetHandler; + + public ClanTips ClanTips; + + private boolean _disabling = false; + + // Spawn area + + public ClansManager(JavaPlugin plugin, String serverName, IncognitoManager incognitoManager, PacketHandler packetHandler, Punish punish, CoreClientManager clientManager, DonationManager donationManager, PreferencesManager preferencesManager, BlockRestore blockRestore, StatsManager statsManager, Teleport teleport, Chat chat, GearManager gearManager, HologramManager hologramManager, InventoryManager inventoryManager) + { + super("Clans Manager", plugin); + + _instance = this; + _punish = punish; + + _packetHandler = packetHandler; + + _incognitoManager = incognitoManager; + _serverName = serverName; + _clientManager = clientManager; + _combatManager = require(CombatManager.class); + _hologramManager = hologramManager; + + _chat = chat; + _blockRestore = blockRestore; + _teleport = teleport; + _warManager = new WarManager(plugin, this); + + _donationManager = donationManager; + _inventoryManager = inventoryManager; + + _blacklist = new ClansBlacklist(plugin); + + _gearManager = gearManager; + _lootManager = new LootManager(gearManager); + _disguiseManager = Managers.get(DisguiseManager.class); + _npcManager = new NpcManager(plugin, Managers.get(Creature.class)); + _condition = new SkillConditionManager(plugin); + _damageManager = new DamageManager(plugin, _combatManager, _npcManager, _disguiseManager, _condition); + _condition.setDamageManager(_damageManager); + + _worldEvent = new WorldEventManager(plugin, this, _damageManager, _lootManager, blockRestore, _clanRegions); + + _taskManager = new TaskManager(plugin, _clientManager); + + ClanTips = new ClanTips(plugin, this, preferencesManager); + + // new MurderManager(plugin, this); + + _clanAdmin = new ClansAdmin(this); + _clanBlocks = new ClansBlocks(); + _clanDisplay = new ClansDisplay(plugin, this); + _clanGame = new ClansGame(plugin, this); + _clanUtility = new ClansUtility(this); + _tutorial = new TutorialManager(plugin, clientManager, donationManager, hologramManager, this, _npcManager, _taskManager); + _itemMapManager = new ItemMapManager(this, _tutorial, _worldEvent); + new TntGeneratorManager(plugin, this); + new SupplyDropManager(plugin); + + new InvseeManager(this); + new MenuManager(plugin); + + _explosion = Managers.get(Explosion.class); + _warPointEvasion = new WarPointEvasion(plugin); + +// new ClansLoginManager(getPlugin(), clientManager, _serverName); + + _clanShop = new ClanShop(this, clientManager, donationManager); + + Energy energy = new Energy(plugin); + // TODO: Re-enable customtagfix with NCP update? + // new CustomTagFix(plugin, packetHandler); + + new Field(plugin, Managers.get(Creature.class), _condition, this, energy, serverName); + + // Required managers to be initialized + new Spawn(plugin, this); + new NPCManager(this, _hologramManager); + _safeLog = new SafeLog(plugin, this); + _observerManager = new ObserverManager(plugin, _condition, this); + + new ClanEnergyTracker(plugin, this); +// new StuckManager(this); + + new PotatoManager(plugin, this); + + new Weapon(plugin, energy); + new Gameplay(plugin, this, blockRestore, _damageManager); + new HiddenChestManager(this); + _projectileManager = new ProjectileManager(plugin); + Fire fire = new Fire(plugin, _condition, _damageManager); + + HashSet itemIgnore = new HashSet(); + itemIgnore.add("Proximity Explosive"); + itemIgnore.add("Proximity Zapper"); + + ItemFactory itemFactory = new ItemFactory(plugin, blockRestore, _condition, _damageManager, energy, fire, _projectileManager, this, itemIgnore); + SkillFactory skillManager = new SkillFactory(plugin, _damageManager, this, _combatManager, _condition, _projectileManager, _disguiseManager, blockRestore, fire, new Movement(plugin), teleport, energy); + skillManager.RemoveSkill("Dwarf Toss", "Block Toss"); + skillManager.removeSkill("Whirlwind Axe"); + skillManager.removeSkill("Shield Smash"); + // Check if any Ice Prison blocks will be placed inside a safe zone or world event + // fixme Is there any way of checking the destination beforehand? + // Although if the user is trying to launch an Ice Prison into a safezone they should know better + skillManager.GetSkill("Ice Prison").setLocationFilter(location -> + { + { + ClanTerritory territory = _clanUtility.getClaim(location); + if (territory != null && territory.Safe) + { + return false; + } + } + { + if (_worldEvent.isInEvent(location, true)) + { + return false; + } + } + + return true; + }); + ((Blink)skillManager.GetSkill("Blink")).setAllowTrapping(true); + + Flash flashSkill = (Flash) skillManager.GetSkill("Flash"); + flashSkill.setAllowTrapping(true); + flashSkill.setStartWithCharges(false); + + registerEvents(new Listener() + { + @EventHandler + public void on(FissureModifyBlockEvent event) + { + Material targetType = event.getTargetBlock().getType(); + event.setCancelled(targetType == Material.POTATO || targetType == Material.CARROT); + } + + @EventHandler + public void on(CustomDamageEvent event) + { + if (event.GetCause() == EntityDamageEvent.DamageCause.CUSTOM + && event.GetDamageInitial() == 0.1 + && event.GetDamageePlayer() != null) + { + Condition poisonShock = _condition.GetActiveCondition(event.GetDamageePlayer(), Condition.ConditionType.POISON_SHOCK); + if (poisonShock != null) + { + event.SetIgnoreArmor(true); + } + } + } + }); + + _classManager = new ClassManager(plugin, _clientManager, donationManager, skillManager, itemFactory); + + // Register redis based server commands + ServerCommandManager.getInstance().registerCommandType(ClanDeleteCommand.class, new ClanDeleteCommandHandler()); + ServerCommandManager.getInstance().registerCommandType(ClanLoadCommand.class, new ClanLoadCommandHandler()); + + EloManager eloManager = Managers.get(EloManager.class); + AchievementManager achievementManager = Managers.get(AchievementManager.class); + ClassShopManager shopManager = new ClassShopManager(plugin, _classManager, skillManager, itemFactory, achievementManager, _clientManager); + _classShop = new ClassCombatShop(shopManager, _clientManager, donationManager, true, "Class Shop"); + + new ClanEnergyManager(this); + + _playTracker = new Playtime(this, statsManager); + + _scoreboard = new ClansScoreboardManager(plugin, this, _warManager, _worldEvent, _tutorial, clientManager, donationManager); + _clanDataAccess = new ClansDataAccessLayer(this, _scoreboard); + + HelmetPacketManager.getInstance(); + _bannerManager = new BannerManager(plugin); + + _goldManager = new GoldManager(this, _clientManager, donationManager, _clanDataAccess); + + for (ClanToken token : _clanDataAccess.getRepository().retrieveClans()) + { + loadClan(token, false); + } + _bannerManager.loadBanners(this); + + require(PersonalServerManager.class); + require(CommunityManager.class); + + Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, "Replay|Restrict"); + + +// new ClaimVisualizer(plugin, this); + + // RedisDataRepository(ConnectionData writeConn, ConnectionData + // readConn, Region region, Class elementType, String elementLabel) + // Initialize default region factions and territory + // (spawn/fields/borderlands) + _clanRegions = new ClansRegions(plugin, this); + _clanRegions.initializeRegions(); + + List jumpOffHolograms = Arrays.asList( + // West Spawn + new Location(Spawn.getSpawnWorld(), 8, 200, 359), + new Location(Spawn.getSpawnWorld(), 34, 200, 390), + new Location(Spawn.getSpawnWorld(), 8, 200, 418), + new Location(Spawn.getSpawnWorld(), -25, 200, 390), + + // East Spawn + new Location(Spawn.getSpawnWorld(), 34, 206, -393), + new Location(Spawn.getSpawnWorld(), 8, 206, -365), + new Location(Spawn.getSpawnWorld(), -25, 206, -393), + new Location(Spawn.getSpawnWorld(), 8, 206, -424) + ); + + List welcomeHolograms = Arrays.asList( + new Location(Spawn.getSpawnWorld(), 17, 200, 390), + new Location(Spawn.getSpawnWorld(), 8, 200, 399), + new Location(Spawn.getSpawnWorld(), 0, 200, 390), + new Location(Spawn.getSpawnWorld(), 8, 200, 381), + new Location(Spawn.getSpawnWorld(), 8, 206, -384), + new Location(Spawn.getSpawnWorld(), 0, 206, -393), + new Location(Spawn.getSpawnWorld(), 8, 206, -402), + new Location(Spawn.getSpawnWorld(), 17, 206, -393) + ); + + for (Location location : jumpOffHolograms) + { + Hologram hologram = new Hologram(hologramManager, location, + C.cGreen + "Jump Off", + C.cGreen + "to begin your Clans adventure!"); + hologram.start(); + } + + for (Location location : welcomeHolograms) + { + Hologram hologram = new Hologram(hologramManager, location, + C.cGreenB + "Welcome to Clans!", + C.cWhite + "Type " + C.cYellow + "/clan" + C.cWhite + " to get started!" + ); + hologram.start(); + } + + + _siegeManager = new SiegeManager(this); + _netherManager = new NetherManager(this); + _amplifierManager = new AmplifierManager(plugin); + + new MountManager(plugin, clientManager, donationManager); + + new BoxManager(plugin); + + new AltManager(); + + _restartManager = new RestartManager(plugin); + + require(CashShopManager.class); + + require(AfkManager.class); + + generatePermissions(); + + ServerOnlineMessage message = new ServerOnlineMessage(); + message.ServerName = UtilServer.getServerName(); + ClansQueueMessenger.getMessenger(UtilServer.getServerName()).transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + } + + private void generatePermissions() + { + PermissionGroup.MOD.revokePermission(Teleport.Perm.TELEPORT_COMMAND); + PermissionGroup.ADMIN.setPermission(Teleport.Perm.TELEPORT_COMMAND, true, true); + + PermissionGroup.PLAYER.setPermission(Perm.CLANS_COMMAND, true, true); + PermissionGroup.PLAYER.setPermission(Perm.ALLY_CHAT_COMMAND, true, true); + PermissionGroup.PLAYER.setPermission(Perm.CLAN_CHAT_COMMAND, true, true); + PermissionGroup.PLAYER.setPermission(Perm.MAP_COMMAND, true, true); + PermissionGroup.PLAYER.setPermission(Perm.SUICIDE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.REGION_CLEAR_COMMAND, true, true); + PermissionGroup.CMOD.setPermission(Perm.SPEED_COMMAND, false, true); + PermissionGroup.ADMIN.setPermission(Perm.SPEED_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.FORCE_JOIN_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.AUTO_OP, true, true); + if (UtilServer.isTestServer()) + { + PermissionGroup.QAM.setPermission(Perm.AUTO_OP, false, true); + } + PermissionGroup.CONTENT.setPermission(Perm.PREFIX_SHOWN, true, true); + PermissionGroup.CONTENT.setPermission(Perm.JOIN_FULL, true, true); + PermissionGroup.BUILDER.setPermission(Perm.PREFIX_SHOWN, true, true); + PermissionGroup.TRAINEE.setPermission(Perm.JOIN_FULL, true, true); + PermissionGroup.PLAYER.setPermission(CoreClientManager.Perm.JOIN_FULL, true, true); + } + + @Override + public void addCommands() + { + addCommand(new ClansCommand(this)); + addCommand(new RegionsCommand(this)); + addCommand(new ClansChatCommand(this)); + addCommand(new ClansAllyChatCommand(this)); + addCommand(new MapCommand(this)); + addCommand(new SpeedCommand(this)); + addCommand(new KillCommand(this)); + } + + public void loadClan(ClanToken clanToken, boolean loadBanner) + { + ClanInfo clan = new ClanInfo(this, clanToken); + _clanMap.put(clanToken.Name, clan); + + for (ClanMemberToken memberToken : clanToken.Members) + { + _clanMemberUuidMap.put(memberToken.PlayerUUID, clan); + // _clanMemberMap.put(memberToken.Name, clan); + } + + for (ClanTerritoryToken territoryToken : clanToken.Territories) + { + String[] split = territoryToken.Chunk.split(","); + ClaimLocation location = ClaimLocation.of(split[0], Integer.parseInt(split[1]), Integer.parseInt(split[2])); + _claimMap.put(location, new ClanTerritory(ClaimLocation.fromStoredString(territoryToken.Chunk), territoryToken.ClanName, territoryToken.Safe)); + } + + if (loadBanner) + { + _bannerManager.loadBanner(clan); + } + } + + public void loadClan(ClanToken clanToken) + { + loadClan(clanToken, true); + } + + public DisguiseManager getDisguiseManager() + { + return _disguiseManager; + } + + public TutorialManager getTutorial() + { + return _tutorial; + } + + public NpcManager getNPCManager() + { + return _npcManager; + } + + public ClansRegions getClanRegions() + { + return _clanRegions; + } + + public DonationManager getDonationManager() + { + return _donationManager; + } + + public GoldManager getGoldManager() + { + return _goldManager; + } + + public InventoryManager getInventoryManager() + { + return _inventoryManager; + } + + public ItemMapManager getItemMapManager() + { + return _itemMapManager; + } + + public Explosion getExplosion() + { + return _explosion; + } + + public PacketHandler getPacketHandler() + { + return _packetHandler; + } + + public BannerManager getBannerManager() + { + return _bannerManager; + } + + public AmplifierManager getAmplifierManager() + { + return _amplifierManager; + } + + public int getInviteExpire() + { + return _inviteExpire; + } + + public NautHashMap getClanMap() + { + return _clanMap; + } + + public Set getClanNameSet() + { + return _clanMap.keySet(); + } + + public NautHashMap getClanMemberUuidMap() + { + return _clanMemberUuidMap; + } + + public static boolean isClaimable(Location location) + { + int x = Math.abs(location.getBlockX()); + int z = Math.abs(location.getBlockZ()); + + return (x <= CLAIMABLE_RADIUS && z <= CLAIMABLE_RADIUS) && !Spawn.getInstance().isSafe(location); + } + + public boolean isFields(Location location) + { + return getClanUtility().isSpecial(location, "Fields"); + } + + public boolean canUnclaimChunk(ClanInfo stealer, ClanInfo owner) + { + return owner.getClaims() > owner.getClaimsMax() && !owner.isAdmin() && !owner.isAlly(stealer); + } + + public ClanInfo getClan(Player player) + { + return getClan(player.getUniqueId()); + } + + public ClanInfo getClan(UUID uuid) + { + return _clanMemberUuidMap.get(uuid); + } + + public boolean isInClan(Player player) + { + return _clanMemberUuidMap.containsKey(player.getUniqueId()); + } + + public ClanInfo getClan(String clan) + { + return _clanMap.get(clan); + } + + /** + * @param clanName + * @return true, if a Clan with matching {@code clanName} exists, false + * otherwise. + */ + public boolean clanExists(String clanName) + { + return getClan(clanName) != null; + } + + public NautHashMap getClaimMap() + { + return _claimMap; + } + + public long lastPower = System.currentTimeMillis(); + + @EventHandler + public void displayHardcoreMode(ServerListPingEvent event) + { + if (Clans.HARDCORE) + { + event.setMotd("Hardcore"); + } + else + { + event.setMotd("Casual"); + } + } + + @EventHandler + public void savePlayerActiveBuild(PlayerQuitEvent event) + { + if (_classManager.Get(event.getPlayer()) != null && _classManager.Get(event.getPlayer()).GetGameClass() != null) + { + CustomBuildToken activeBuild = _classManager.Get(event.getPlayer()).GetActiveCustomBuild(_classManager.Get(event.getPlayer()).GetGameClass()); + + if (activeBuild == null) return; + + activeBuild.PlayerName = event.getPlayer().getName(); + + // 0 is set aside for active build so we just dupe build to this row + // whenever we update it. + activeBuild.CustomBuildNumber = 0; + _classManager.GetRepository().SaveCustomBuild(activeBuild); + } + } + + @EventHandler + public void StaffIncognito(IncognitoStatusChangeEvent event) + { + if (event.getNewState()) + { + UtilServer.broadcast(F.sys("Quit", event.getPlayer().getName())); + } + else + { + UtilServer.broadcast(F.sys("Join", event.getPlayer().getName())); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Join(PlayerJoinEvent event) + { + event.setJoinMessage(null); + UtilPlayer.message(event.getPlayer(), C.cDAquaB + "Welcome to Mineplex Clans!"); + + if (_incognitoManager.Get(event.getPlayer()).Status) + { + return; + } + + for (Player other : UtilServer.getPlayers()) + { + if (_tutorial.inTutorial(other)) + { + // Don't display join message if player in tutorial. + continue; + } + + other.sendMessage(F.sys("Join", event.getPlayer().getName())); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Quit(PlayerQuitEvent event) + { + event.setQuitMessage(null); + + if (_incognitoManager.Get(event.getPlayer()).Status) + { + return; + } + + for (Player other : UtilServer.getPlayers()) + { + if (_tutorial.inTutorial(other)) + { + // Don't display quit message if player in tutorial. + continue; + } + + other.sendMessage(F.sys("Quit", event.getPlayer().getName())); + } + } + + @EventHandler + public void disableEnderpeal(PlayerInteractEvent event) + { + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) + { + ItemStack item = event.getPlayer().getItemInHand(); + if (item != null && item.getType() == Material.ENDER_PEARL) event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void BlockCreatureSpawn(CreatureSpawnCustomEvent event) + { + ClanInfo clan = _clanUtility.getOwner(event.GetLocation()); + + if (clan != null && !clan.isAdmin() && !clan.getName().equals("Spawn") && event.getReason() != SpawnReason.CUSTOM) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void Interact(PlayerInteractEvent event) + { + getClanGame().Interact(event); + } + + @EventHandler + public void join(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + ClanInfo clanInfo = _clanMemberUuidMap.get(player.getUniqueId()); + if (clanInfo != null) + { + clanInfo.playerOnline(player); + } + + if (_clientManager.Get(player).hasPermission(Perm.AUTO_OP)) + { + player.setOp(true); + } + if (player.getInventory().getHelmet() != null) //Reset helmet to fix 1 damage bug + { + ItemStack helmet = player.getInventory().getHelmet().clone(); + player.getInventory().setHelmet(null); + runSyncLater(() -> + { + player.getInventory().setHelmet(helmet); + }, 20L); + } + } + + @EventHandler + public void disallowReplayMod(PlayerJoinEvent event) + { + // happens 20 ticks later because player channels don't + // seem to work immediately after joining. + runSyncLater(() -> + { + ByteArrayDataOutput bado = ByteStreams.newDataOutput(); + + bado.writeUTF("no_xray"); + bado.writeBoolean(true); + + bado.writeUTF("no_noclip"); + bado.writeBoolean(true); + + bado.writeUTF("only_recording_player"); + bado.writeBoolean(true); + + event.getPlayer().sendPluginMessage(_plugin, "Replay|Restrict", bado.toByteArray()); + }, 20L); + } + + @EventHandler + public void denyBow(EntityShootBowEvent event) + { + if (event.getEntity() instanceof Player) + { + Player player = ((Player) event.getEntity()); + ClientClass client = _classManager.Get(player); + if (client.IsGameClass(IPvpClass.ClassType.Mage) || client.IsGameClass(IPvpClass.ClassType.Knight) || client.IsGameClass(IPvpClass.ClassType.Brute)) + { + event.setCancelled(true); + UtilPlayer.message(player, F.main("Clans", "You cannot use " + F.elem("Bow") + " as a " + F.elem(client.GetGameClass().GetName()))); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void commandPreProcess(PlayerCommandPreprocessEvent event) + { + String[] messages = { "ver", "version", "pl", "plugins"}; + + for (String message : messages) + { + if (!event.getMessage().equalsIgnoreCase("/" + message) && !event.getMessage().toLowerCase().startsWith("/" + message + " ")) + { + continue; + } + + UtilPlayer.message(event.getPlayer(), F.main("Clans", "Server is running Mineplex Clans version " + _plugin.getDescription().getVersion() + "!")); + event.setCancelled(true); + } + } + + @EventHandler + public void quit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + ClanInfo clanInfo = getClanMemberUuidMap().get(player.getUniqueId()); + if (clanInfo != null) + { + clanInfo.playerOffline(player); + } + } + + private void handleClanChat(Player player, String message, ClanInfo clan, String rank) + { + message = _chat.filterMessage(player, true, message); + + if (message.isEmpty()) + { + return; + } + + for (Player cur : clan.getOnlinePlayers()) + { + UtilPlayer.message(cur, String.format(rank + C.cAqua + "%s " + C.cDAqua + "%s", player.getName(), message)); + } + } + + private void handleAllyChat(Player player, String message, ClanInfo clan, String rank) + { + final String filtered = _chat.filterMessage(player, true, message); + + if (filtered.isEmpty()) + { + return; + } + + List recipients = new ArrayList<>(clan.getOnlinePlayers()); + + for (String allyName : clan.getAllyMap().keySet()) + { + ClanInfo ally = _clanUtility.getClanByClanName(allyName); + if (ally == null) continue; + + recipients.addAll(ally.getOnlinePlayers()); + } + + recipients.forEach(p -> UtilPlayer.message(p, String.format(rank + C.cDGreen + clan.getName() + " " + C.cDGreen + "%s " + C.cGreen + "%s", player.getName(), filtered))); + + recipients.clear(); + } + + private void handleRegularChat(FormatPlayerChatEvent event, ClanInfo clan, String rank) + { + String message = _chat.filterMessage(event.getPlayer(), true, event.getMessage()); + + if (message.isEmpty()) + { + return; + } + + if (clan == null) + { + for (Player other : event.getRecipients()) + { + if (_tutorial.inTutorial(other)) + { + continue; + } + + UtilPlayer.message(other, String.format(rank + C.cYellow + "%s " + C.cWhite + "%s", event.getPlayer().getName(), message)); + } + return; + } + + List recipients = new ArrayList<>(); + + for (Player other : event.getRecipients()) + { + if (_tutorial.inTutorial(other)) + { + continue; + } + + ClanInfo otherClan = _clanUtility.getClanByPlayer(other); + + if (otherClan == null) + { + recipients.add(other); + } + else + { + ClanRelation rel = _clanUtility.rel(clan, otherClan); + other.sendMessage(rank + rel.getColor(true) + clan.getName() + " " + rel.getColor(false) + event.getPlayer().getName() + " " + C.cWhite + message); + } + } + + recipients.forEach(p -> p.sendMessage(String.format(rank + C.cGold + clan.getName() + " " + C.cYellow + "%s " + C.cWhite + "%s", event.getPlayer().getName(), message))); + + recipients.clear(); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void disableObsidian(BlockBreakEvent event) + { + if (event.getBlock().getType().equals(Material.OBSIDIAN)) + { + event.setCancelled(true); + event.getBlock().setType(Material.AIR); + } + } + + @EventHandler + public void onSignChange(SignChangeEvent event) + { + PunishClient punishclient = _punish.GetClient(event.getPlayer().getName()); + + if (punishclient != null && punishclient.IsMuted()) + { + for (int i = 0; i < event.getLines().length; i++) + { + event.setLine(i, ""); + } + } + } + + @EventHandler(ignoreCancelled = true) + public void handlePlayerChat(FormatPlayerChatEvent event) + { + if (event.getChatChannel() == ChatChannel.COMMUNITY) + { + return; + } + + ClientClan client = Get(event.getPlayer()); + + if (client == null) + { + return; + } + + ClanInfo clan = _clanUtility.getClanByPlayer(event.getPlayer()); + + String rank = _clientManager.Get(event.getPlayer()).getPrimaryGroup().getDisplay(true, true, true, false) + " "; + + if (!_clientManager.Get(event.getPlayer()).hasPermission(Perm.PREFIX_SHOWN)) + { + rank = ""; + } + + if (client.isClanChat() && clan != null) + { + handleClanChat(event.getPlayer(), event.getMessage(), clan, rank); + } + else if (client.isAllyChat() && clan != null) + { + handleAllyChat(event.getPlayer(), event.getMessage(), clan, rank); + } + else + { + handleRegularChat(event, clan, rank); + } + + event.setCancelled(true); + + System.out.println((clan == null ? "" : clan.getName()) + " " + _clientManager.Get(event.getPlayer()).getPrimaryGroup().name() + " " + event.getPlayer().getName() + " " + event.getMessage()); + } + + + public void messageClan(ClanInfo clan, String message) + { + for (Player player : clan.getOnlinePlayers()) + { + UtilPlayer.message(player, message); + } + } + + public void sendTipToClan(ClanInfo clan, TipType tip) + { + for (Player player : clan.getOnlinePlayers()) + { + ClanTips.displayTip(tip, player); + } + } + + public void middleTextClan(ClanInfo clan, String header, String footer) + { + middleTextClan(clan, header, footer, 20, 60, 20); + } + + public void middleTextClan(ClanInfo clan, String header, String footer, int fadeInTicks, int stayTicks, int fadeOutTicks) + { + UtilTextMiddle.display(header, footer, fadeInTicks, stayTicks, fadeOutTicks, clan.getOnlinePlayersArray()); + } + + public void chatClan(ClanInfo clan, Player caller, String message) + { + String rank = _clientManager.Get(caller).getPrimaryGroup().getDisplay(true, true, true, false) + " "; + + if (!_clientManager.Get(caller).hasPermission(Perm.PREFIX_SHOWN)) + { + rank = ""; + } + + handleClanChat(caller, message, clan, rank); + } + + public void chatAlly(ClanInfo clan, Player caller, String message) + { + String rank = _clientManager.Get(caller).getPrimaryGroup().getDisplay(true, true, true, false) + " "; + + if (!_clientManager.Get(caller).hasPermission(Perm.PREFIX_SHOWN)) + { + rank = ""; + } + + handleAllyChat(caller, message, clan, rank); + } + + public int getNameMin() + { + return _nameMin; + } + + public int getNameMax() + { + return _nameMax; + } + + public long getReclaimTime() + { + return _reclaimTime; + } + + public boolean canHurt(Player a, Player b) + { + if (a.equals(b)) return false; + + return _clanUtility.canHurt(a, b); + } + + public boolean canHurt(String a, String b) + { + if (a.equals(b)) return false; + + return _clanUtility.canHurt(UtilPlayer.searchExact(a), UtilPlayer.searchExact(b)); + } + + public boolean isSafe(Player a) + { + return _clanUtility.isSafe(a); + } + + // public ClanRelation getRelation(String playerA, String playerB) + // { + // return getClanUtility().rel(_clanMemberMap.get(playerA), + // _clanMemberMap.get(playerB)); + // } + + public ClanRelation getRelation(Player playerA, Player playerB) + { + return getRelation(playerA.getUniqueId(), playerB.getUniqueId()); + } + + public ClanRelation getRelation(UUID playerA, UUID playerB) + { + return getClanUtility().rel(getClanMemberUuidMap().get(playerA), getClanMemberUuidMap().get(playerB)); + } + + public long getOnlineTime() + { + return _onlineTime; + } + + public CombatManager getCombatManager() + { + return _combatManager; + } + + public ClansUtility getClanUtility() + { + return _clanUtility; + } + + @Override + protected ClientClan addPlayer(UUID uuid) + { + return new ClientClan(); + } + + public BlockRestore getBlockRestore() + { + return _blockRestore; + } + + public ClansDataAccessLayer getClanDataAccess() + { + return _clanDataAccess; + } + + public Teleport getTeleport() + { + return _teleport; + } + + public ClansDisplay getClanDisplay() + { + return _clanDisplay; + } + + public NautHashMap getUnclaimMap() + { + return _unclaimMap; + } + + public ClansAdmin getClanAdmin() + { + return _clanAdmin; + } + + public ClansGame getClanGame() + { + return _clanGame; + } + + public ClansBlocks getClanBlocks() + { + return _clanBlocks; + } + + public String getServerName() + { + return _serverName; + } + + public CoreClientManager getClientManager() + { + return _clientManager; + } + + public ConditionManager getCondition() + { + return _condition; + } + + public ClassCombatShop getClassShop() + { + return _classShop; + } + + public ClanShop getClanShop() + { + return _clanShop; + } + + public WarManager getWarManager() + { + return _warManager; + } + + public ProjectileManager getProjectile() + { + return _projectileManager; + } + + public WorldEventManager getWorldEvent() + { + return _worldEvent; + } + + public HologramManager getHologramManager() + { + return _hologramManager; + } + + public GearManager getGearManager() + { + return _gearManager; + } + + public LootManager getLootManager() + { + return _lootManager; + } + + public Chat getChat() + { + return _chat; + } + + public ClansScoreboardManager getScoreboard() + { + return _scoreboard; + } + + /** + * Get the timezone for this server. This may be used in the future if we + * have clans servers with varying timezones. + * + * @return {@link java.util.TimeZone} that this server should run at + */ + public TimeZone getServerTimeZone() + { + return TIME_ZONE; + } + + @Override + public void disable() + { + // Kind of confusing, Clans.java calls this so that we can pass the + // disable event to WorldEventManager + // This is so that we can prevent any permanent world changes with + // events + _disabling = true; + _blockRestore.onDisable(); + _worldEvent.onDisable(); + _goldManager.onDisable(); + _playTracker.onDisable(); + _netherManager.onDisable(); + _safeLog.onDisable(); + _restartManager.onDisable(); + _observerManager.onDisable(); + Managers.get(MountManager.class).onDisable(); + Managers.get(SupplyDropManager.class).onDisable(); + ServerOfflineMessage message = new ServerOfflineMessage(); + message.ServerName = UtilServer.getServerName(); + ClansQueueMessenger.getMessenger(UtilServer.getServerName()).transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + } + + @EventHandler + public void transmitQueueStatus(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + int online = 0; + + for (Player player : UtilServer.getPlayers()) + { + if (_clientManager.Get(player).hasPermission(Perm.JOIN_FULL)) + { + continue; + } + + online++; + } + + ClansServerStatusMessage message = new ClansServerStatusMessage(); + message.ServerName = UtilServer.getServerName(); + message.OpenSlots = Math.max(0, Bukkit.getMaxPlayers() - online); + message.Online = !_restartManager.isRestarting() && !_disabling; + ClansQueueMessenger.getMessenger(UtilServer.getServerName()).transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + } + + @EventHandler + public void hunger(FoodLevelChangeEvent event) + { + if (event.getFoodLevel() < ((Player) event.getEntity()).getFoodLevel() && _clanUtility.getClaim(event.getEntity().getLocation())!=null && _clanUtility.getClaim(event.getEntity().getLocation()).isSafe(event.getEntity().getLocation())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void hubCommand(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().toLowerCase().equals("/lobby") || event.getMessage().toLowerCase().equals("/hub") || event.getMessage().toLowerCase().equals("/leave")) + { + Portal.getInstance().sendPlayerToGenericServer(event.getPlayer(), GenericServer.CLANS_HUB, Intent.PLAYER_REQUEST); + event.setCancelled(true); + } + } + + @EventHandler + public void openShop(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().equals("/cgui")) + { + _clanShop.attemptShopOpen(event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void updateBedStatus(UpdateEvent event) + { + if (event.getType() != UpdateType.TWOSEC) + { + return; + } + + for (String name : getClanNameSet()) + { + ClanInfo clan = _clanUtility.getClanByClanName(name); + + if (clan.getHome() != null) + { + if (UtilBlock.isValidBed(clan.getHome())) + { + if (clan.getHome().clone().add(0, 1,0).getBlock().getType().equals(Material.AIR)) + { + clan.setBedStatus(BedStatus.EXISTS_AND_UNOBSTRUCTED); + } + else + { + clan.setBedStatus(BedStatus.EXISTS_AND_OBSTRUCTED); + } + } + else + { + clan.setBedStatus(BedStatus.DESTROYED); + } + } + else + { + clan.setBedStatus(BedStatus.DOESNT_EXIST); + } + } + } + + @EventHandler + public void message(PlayerMessageEvent event) + { + if (!_tutorial.inTutorial(event.getPlayer())) + { + return; + } + + if (event.getMessage().startsWith(C.cBlue + "Death>")) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void handleClansDeath(PlayerDeathEvent event) + { + PlayerClan playerClan; + PlayerClan killerClan = null; + + Player player = event.getEntity(); + ClanInfo pClan = _clanMemberUuidMap.get(player.getUniqueId()); + playerClan = new PlayerClan(player, pClan); + + if (player.getKiller() != null) + { + Player killer = player.getKiller(); + ClanInfo kClan = _clanMemberUuidMap.get(killer.getUniqueId()); + killerClan = new PlayerClan(killer, kClan); + } + + ClansPlayerDeathEvent clansPlayerDeathEvent = new ClansPlayerDeathEvent(event, playerClan, killerClan); + Bukkit.getServer().getPluginManager().callEvent(clansPlayerDeathEvent); + } + + public void justLeft(UUID uniqueId, ClanInfo clan) + { + _clanMemberLeftMap.put(uniqueId, Pair.create(clan, System.currentTimeMillis())); + } + + public void resetLeftTimer(UUID uuid) + { + _clanMemberLeftMap.remove(uuid); + _warPointEvasion.resetCooldown(uuid); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void setWalkSpeed(PlayerJoinEvent event) + { + event.getPlayer().setWalkSpeed(0.2f); + } + + @EventHandler + public void disableHorses(VehicleEnterEvent event) + { + if (event.getEntered() instanceof Player && event.getVehicle() instanceof Horse) + { + if (!Recharge.Instance.use((Player) event.getEntered(), "Ride Horse", 2 * 20L, true, false)) + { + event.setCancelled(true); + } + } + } + + public Pair leftRecently(UUID uniqueId, long time) + { + if (_clanMemberLeftMap.containsKey(uniqueId) && (System.currentTimeMillis() - _clanMemberLeftMap.get(uniqueId).getRight()) <= time) + { + return Pair.create(_clanMemberLeftMap.get(uniqueId).getLeft(), time - (System.currentTimeMillis() - _clanMemberLeftMap.get(uniqueId).getRight())); + } + + return null; + } + + public ObserverManager getObserverManager() + { + return _observerManager; + } + + + public int getServerId() + { + return _clanDataAccess.getRepository().getServerId(); + } + + public NetherManager getNetherManager() + { + return _netherManager; + } + + public void message(Player player, String message) + { + UtilPlayer.message(player, F.main("Clans", message)); + } + + public DamageManager getDamageManager() + { + return _damageManager; + } + + public boolean hasTimer(Player player) + { + return _timerManager.hasTimer(player); + } + + public ClansBlacklist getBlacklist() + { + return _blacklist; + } + + public SiegeManager getSiegeManager() + { + return _siegeManager; + } + + public IncognitoManager getIncognitoManager() + { + return _incognitoManager; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayer.java new file mode 100644 index 00000000..b18b93ef --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayer.java @@ -0,0 +1,54 @@ +package mineplex.game.clans.clans; + +import java.util.UUID; + +public class ClansPlayer +{ + private String _playerName; + private UUID _uuid; + private ClanRole _role; + private boolean _online; + + public ClansPlayer(String playerName, UUID uuid, ClanRole role) + { + _playerName = playerName; + _uuid = uuid; + _role = role; + _online = false; + } + + public String getPlayerName() + { + return _playerName; + } + + public UUID getUuid() + { + return _uuid; + } + + public ClanRole getRole() + { + return _role; + } + + public void setRole(ClanRole role) + { + _role = role; + } + + public void setPlayerName(String playerName) + { + _playerName = playerName; + } + + public boolean isOnline() + { + return _online; + } + + public void setOnline(boolean online) + { + _online = online; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerComparator.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerComparator.java new file mode 100644 index 00000000..593109d4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerComparator.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans; + +import java.util.Comparator; + +public class ClansPlayerComparator implements Comparator +{ + @Override + public int compare(ClansPlayer o1, ClansPlayer o2) + { + if (o1 == null || o2 == null) + return 0; + + if (o1.isOnline() != o2.isOnline()) + { + return o1.isOnline() ? -1 : 1; + } + + if (o1.getRole() != o2.getRole()) + { + return o2.getRole().ordinal() - o1.getRole().ordinal(); + } + + return o1.getPlayerName().compareTo(o2.getPlayerName()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerStats.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerStats.java new file mode 100644 index 00000000..6b8d4542 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerStats.java @@ -0,0 +1,18 @@ +package mineplex.game.clans.clans; + +public enum ClansPlayerStats +{ + PLAY_TIME("Clans.TimePlaying"); + + private String _id; + + ClansPlayerStats(String id) + { + _id = id; + } + + public String id() + { + return _id; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerTasks.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerTasks.java new file mode 100644 index 00000000..1cd37cb5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansPlayerTasks.java @@ -0,0 +1,18 @@ +package mineplex.game.clans.clans; + +public enum ClansPlayerTasks +{ + FIRST_SESSION("Clans.FirstSession"); + + private String _id; + + ClansPlayerTasks(String id) + { + _id = id; + } + + public String id() + { + return _id; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansUtility.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansUtility.java new file mode 100644 index 00000000..e37f0242 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansUtility.java @@ -0,0 +1,1262 @@ +package mineplex.game.clans.clans; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.event.ClanDisbandedEvent; +import mineplex.game.clans.clans.event.PlayerClaimTerritoryEvent; +import mineplex.game.clans.clans.event.PlayerPreClaimTerritoryEvent; +import mineplex.game.clans.clans.event.PlayerUnClaimTerritoryEvent; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.spawn.Spawn; + +public class ClansUtility +{ + // The maximum number of clans to search before exiting early. Inclusive + private static final int MAX_CLAN_SEARCH = 10; + // The maximum number of players to search before exiting early. Inclusive + private static final int MAX_PLAYER_SEARCH = 10; + + private ClansManager _clansManager; + + public ClansUtility(ClansManager clans) + { + _clansManager = clans; + } + + public enum ClanRelation + { + SELF(C.xSelf, C.xdSelf), + ALLY(C.xAlly, C.xdAlly), + ALLY_TRUST(C.xAlly, C.xdAlly), + WAR_WINNING(C.xWarWinning, C.xdWarWinning), + WAR_LOSING(C.xWarLosing, C.xdWarLosing), + NEUTRAL(C.xNeutral, C.xdNeutral), + ADMIN(C.xAdmin, C.xAdmin), + SAFE(C.xSafe, C.xSafe); + + private ChatColor _light; + private ChatColor _dark; + + ClanRelation(ChatColor light, ChatColor dark) + { + _light = light; + _dark = dark; + } + + public String getPrefix() + { + return _light.toString(); + } + + public ChatColor getColor(boolean dark) + { + return dark ? _dark : _light; + } + } + + /** + * + * @param location + * @param radius + * @return a 2D array of {@link ClanTerritory} with uniform dimension of ( + * {@code radius} * 2 + 1). The region represented by the array of + * territories is centered on {@code location} chunk with a given + * chunk {@code radius}. + */ + public List getTerritory(Location location, int radius, ClanInfo surveyorClan) + { + World world = location.getWorld(); + Chunk chunk = location.getChunk(); + int chunkX = chunk.getX(); + int chunkZ = chunk.getZ(); + int width = radius * 2 + 1; + + List chunks = new ArrayList(); + + for (int x = 0; x < width; x++) + { + for (int z = 0; z < width; z++) + { + int territoryX = chunkX - radius + x; + int territoryZ = chunkZ - radius + z; + ClanTerritory territory = getClaim(world.getChunkAt(territoryX, territoryZ)); + + if (territory != null) + { + ClanInfo clan = getOwner(territory); + String clanName = territory.Owner; + ClanRelation relationship = rel(surveyorClan, clan); + ChatColor color = relChatColor(relationship, false); + + ChunkData data = new ChunkData(territoryX, territoryZ, color, clanName); + + chunks.add(data); + } + } + } + + return chunks; + } + + public ClanInfo searchClanPlayer(Player caller, String name, boolean inform) + { + // CLAN + List clanMatchList = new ArrayList<>(MAX_CLAN_SEARCH); + + for (ClanInfo cur : _clansManager.getClanMap().values()) + { + if (cur.getName().equalsIgnoreCase(name)) return cur; + + if (cur.getName().toLowerCase().contains(name.toLowerCase())) clanMatchList.add(cur); + + if (clanMatchList.size() > MAX_CLAN_SEARCH) break; + } + + if (clanMatchList.size() == 1) return clanMatchList.get(0); + + // PLAYER + List playerMatchList = new ArrayList<>(MAX_PLAYER_SEARCH); + + outer: for (ClanInfo clanInfo : _clansManager.getClanMap().values()) + { + for (ClansPlayer player : clanInfo.getMembers().values()) + { + if (player.getPlayerName().equalsIgnoreCase(name)) return clanInfo; + + if (player.getPlayerName().toLowerCase().contains(name.toLowerCase())) + { + playerMatchList.add(clanInfo); + // No duplicate results please + continue outer; + } + + if (playerMatchList.size() > MAX_PLAYER_SEARCH) break outer; + } + } + + if (playerMatchList.size() == 1) return playerMatchList.get(0); + + if (inform) + { + UtilPlayer.message(caller, F.main("Clan Search", "" + C.mCount + (clanMatchList.size() + playerMatchList.size()) + C.mBody + " matches for [" + C.mElem + name + C.mBody + "].")); + + if (clanMatchList.size() > MAX_CLAN_SEARCH) + { + UtilPlayer.message(caller, F.main("Clan Search", "Too many clans matched. Try a more specific search")); + } + else if (clanMatchList.size() == 0) + { + UtilPlayer.message(caller, F.main("Clan Search", "No clans matched. Try a more specific search")); + } + else + { + StringBuilder clanMatchString = new StringBuilder(); + for (ClanInfo clanInfo : clanMatchList) + { + clanMatchString.append(clanInfo.getName()).append(" "); + } + UtilPlayer.message(caller, F.desc("Matches via Clan", clanMatchString.toString())); + } + if (playerMatchList.size() > MAX_PLAYER_SEARCH) + { + UtilPlayer.message(caller, F.main("Clan Search", "Too many players matched. Try a more specific search")); + } + else if (playerMatchList.size() == 0) + { + UtilPlayer.message(caller, F.main("Clan Search", "No players matched. Try a more specific search")); + } + else + { + StringBuilder playerMatchString = new StringBuilder(); + for (ClanInfo clanInfo : playerMatchList) + { + playerMatchString.append(clanInfo.getName()).append(" "); + } + UtilPlayer.message(caller, F.desc("Matches via Player", playerMatchString.toString())); + } + } + + return null; + } + + public ClanInfo searchClan(Player caller, String name, boolean inform) + { + LinkedList matchList = new LinkedList(); + + for (ClanInfo cur : _clansManager.getClanMap().values()) + { + if (cur.getName().equalsIgnoreCase(name)) return cur; + + if (cur.getName().toLowerCase().contains(name.toLowerCase())) matchList.add(cur); + } + + // No / Non-Unique + if (matchList.size() != 1) + { + if (!inform) return null; + + // Inform + UtilPlayer.message(caller, F.main("Clan Search", "" + C.mCount + matchList.size() + C.mBody + " matches for [" + C.mElem + name + C.mBody + "].")); + + if (matchList.size() > 0) + { + String matchString = ""; + for (ClanInfo cur : matchList) + matchString += cur.getName() + " "; + + UtilPlayer.message(caller, F.main("Clan Search", "" + C.mBody + " Matches [" + C.mElem + matchString + C.mBody + "].")); + } + + return null; + } + + return matchList.get(0); + } + + public ClanInfo getClanByClanName(String clan) + { + return _clansManager.getClan(clan); + } + + public ClanInfo getClanById(int id) + { + for (ClanInfo clan : _clansManager.getClanMap().values()) + { + if (clan.getId() == id) + { + return clan; + } + } + + return null; + } + + public ClanInfo getClanByPlayer(Player player) + { + return getClanByUUID(player.getUniqueId()); + } + + public ClanInfo getClanByUUID(UUID uuid) + { + return _clansManager.getClanMemberUuidMap().get(uuid); + } + + // @Deprecated + // public ClanInfo getClanByPlayer(String name) + // { + // if (!Clans.getClanMemberMap().containsKey(name)) + // return null; + // + // return Clans.getClanMemberMap().get(name); + // } + + public ClanRole getRole(Player player) + { + try + { + return getClanByPlayer(player).getMembers().get(player.getUniqueId()).getRole(); + } + catch (Exception e) + { + return ClanRole.NONE; + } + } + + public boolean isSafe(Player player) + { + if (!UtilTime.elapsed(_clansManager.getCombatManager().getLog(player).GetLastCombatEngaged(), Spawn.COMBAT_TAG_DURATION)) return false; + + return isSafe(player.getLocation()); + } + + public boolean isSafe(Location loc) + { + if (_clansManager.getNetherManager().getNetherWorld().equals(loc.getWorld())) + { + if (_clansManager.getNetherManager().isInSpawn(loc)) + { + return true; + } + } + // Fix for PC-279 + // Do not change to getChunk + // PlayerList#updatePlayers -> iterator -> PlayerVelocityEvent -> getChunk -> loadChunk -> loadPersistentEntities -> addTracker -> ITERATE ON SAME SET + int chunkX = loc.getBlockX() >> 4; + int chunkZ = loc.getBlockZ() >> 4; + ClaimLocation claim = ClaimLocation.of(loc.getWorld().getName(), chunkX, chunkZ); + if (!_clansManager.getClaimMap().containsKey(claim)) return false; + + return _clansManager.getClaimMap().get(claim).isSafe(loc); + } + + public boolean isChunkHome(ClanInfo clan, Chunk chunk) + { + if (clan == null) return false; + + if (clan.getHome() == null) return false; + + return clan.getHome().getChunk().equals(chunk); + } + + public ClanTerritory getClaim(Chunk chunk) + { + ClaimLocation chunkTag = ClaimLocation.of(chunk); + return _clansManager.getClaimMap().get(chunkTag); + } + + /** + * Get formatted name of display as shown for clanB + */ + public String name(ClanInfo display, ClanInfo clanB) + { + return rel(display, clanB).getPrefix() + display.getName(); + } + + public ClanTerritory getClaim(Location loc) + { + return getClaim(loc.getChunk()); + } + + public ClanTerritory getClaim(ClaimLocation location) + { + return _clansManager.getClaimMap().get(location); + } + + public ClanInfo getOwner(ClaimLocation chunk) + { + ClanTerritory claim = getClaim(chunk); + + if (claim == null) return null; + + return getOwner(claim); + } + + public ClanInfo getOwner(Location loc) + { + ClanTerritory claim = getClaim(loc); + + if (claim != null) return getOwner(claim); + + return null; + } + + public boolean isNearAdminClaim(Location location) + { + for (int xOffset = -1; xOffset <= 1; xOffset++) + { + for (int zOffset = -1; zOffset <= 1; zOffset++) + { + if (xOffset == 0 && zOffset == 0) continue; + + ClaimLocation other = ClaimLocation.of(location.getWorld().getChunkAt(location.getChunk().getX() + xOffset, location.getChunk().getZ() + zOffset)); + + ClanInfo adjClan = getOwner(other); + + if (adjClan != null && adjClan.isAdmin() && !adjClan.getName().equalsIgnoreCase("Wilderness")) + { + return true; + } + } + } + + return false; + } + + public ClanInfo getOwner(ClanTerritory claim) + { + return getClanByClanName(claim.Owner); + } + + public String getOwnerString(Location loc) + { + ClanInfo owner = getOwner(loc); + + if (owner == null) return "Wilderness"; + + return owner.getName(); + } + + public String getOwnerStringRel(Location loc, Player player) + { + ClanRelation rel = relPT(player, ClaimLocation.of(loc.getChunk())); + return mRel(rel, getOwnerString(loc), true); + } + + public boolean isClaimed(Location loc) + { + ClaimLocation chunk = ClaimLocation.of(loc.getChunk()); + + return _clansManager.getClaimMap().containsKey(chunk); + } + + // public boolean isAlliance(String player, Location loc) + // { + // if (!Clans.getClanMemberMap().containsKey(player)) + // return false; + // + // if (!isClaimed(loc)) + // return false; + // + // return + // getOwner(getClaim(loc)).isAlly(Clans.getClanMemberMap().get(player).getName()); + // } + + public boolean isSelf(Player player, Location loc) + { + ClanInfo clan = _clansManager.getClan(player); + + if (clan == null) return false; + + if (!isClaimed(loc)) return false; + + return getOwner(getClaim(loc)).isSelf(clan.getName()); + } + + public boolean isAdmin(Location loc) + { + if (!isClaimed(loc)) return false; + + return getOwner(getClaim(loc)).isAdmin(); + } + + public boolean isSpecial(Location loc, String special) + { + if (!isClaimed(loc)) return false; + + if (!isAdmin(loc)) return false; + + return getOwner(getClaim(loc)).getName().toLowerCase().contains(special.toLowerCase()); + } + + public ClanRelation getAccess(Player player, Location loc) + { + ClanInfo owner = getOwner(loc); + ClanInfo clan = getClanByPlayer(player); + + String mimic = _clansManager.Get(player).getMimic(); + + if (mimic.length() != 0) clan = _clansManager.getClanUtility().searchClanPlayer(player, mimic, false); + + if (owner == null) return ClanRelation.SELF; + + if (owner.equals(clan)) return ClanRelation.SELF; + + if (clan != null) if (owner.getTrust(clan.getName())) return ClanRelation.ALLY_TRUST; + + if (clan != null) if (owner.isAlly(clan.getName())) return ClanRelation.ALLY; + + return ClanRelation.NEUTRAL; + } + + // Player Player + public ClanRelation relPP(Player pA, Player pB) + { + return rel(getClanByPlayer(pA), getClanByPlayer(pB)); + } + + // Clan Clan + public ClanRelation relCC(String cA, String cB) + { + return rel(searchClan(null, cA, false), searchClan(null, cB, false)); + } + + // Territory Territory + public ClanRelation relTT(ClaimLocation tA, ClaimLocation tB) + { + return rel(getOwner(tA), getOwner(tB)); + } + + // Player Clan + public ClanRelation relPC(Player pA, String cB) + { + return rel(getClanByPlayer(pA), searchClan(null, cB, false)); + } + + // Player Clan (Object) + public ClanRelation relPC(Player pA, ClanInfo cB) + { + return rel(getClanByPlayer(pA), cB); + } + + // Player Territory + public ClanRelation relPT(Player player, ClaimLocation territory) + { + ClanTerritory claim = getClaim(territory); + if (claim != null && claim.isSafe(player.getLocation())) + { + return ClanRelation.SAFE; + } + + return rel(getClanByPlayer(player), getOwner(territory)); + } + + // Clan Territory + public ClanRelation relCT(String cA, ClaimLocation tB) + { + ClanTerritory claim = getClaim(tB); + if (claim != null) if (claim.Safe) return ClanRelation.SAFE; + + return rel(searchClan(null, cA, false), getOwner(tB)); + } + + public ClanRelation rel(ClanInfo cA, ClanInfo cB) + { + if (cA == null || cB == null) return ClanRelation.NEUTRAL; + + // Self + if (cA.isAdmin() || cB.isAdmin()) return ClanRelation.ADMIN; + + if (cA.getName().equals(cB.getName())) return ClanRelation.SELF; + + // Ally + if (cA.getTrust(cB.getName())) return ClanRelation.ALLY_TRUST; + + if (cA.isAlly(cB.getName())) return ClanRelation.ALLY; + + // War + int warPoints = cA.getWarPoints(cB); + if (warPoints >= 10) + return ClanRelation.WAR_WINNING; + else if (warPoints <= -10) return ClanRelation.WAR_LOSING; + + return ClanRelation.NEUTRAL; + } + + public ChatColor relChatColor(ClanRelation relation, boolean dark) + { + return relation.getColor(dark); + } + + public String relColor(ClanRelation relation, boolean dark) + { + if (relation == ClanRelation.SAFE) return C.xAdmin + "(" + C.xSafe + "SAFE" + C.xAdmin + ") "; + + return relChatColor(relation, dark) + ""; + } + + public String mRel(ClanRelation relation, String message, boolean dark) + { + return relColor(relation, dark) + message + C.mChat; + } + + public boolean playerSelf(Player pA, Player pB) + { + ClanInfo cA = getClanByPlayer(pA); + ClanInfo cB = getClanByPlayer(pB); + + if (cA == null || cB == null) return false; + + return cA.isSelf(cB.getName()); + } + + public boolean playerAlly(Player pA, Player pB) + { + ClanInfo cA = getClanByPlayer(pA); + ClanInfo cB = getClanByPlayer(pB); + + if (cA == null || cB == null) return false; + + return cA.isAlly(cB.getName()); + } + + public boolean playerEnemy(Player pA, Player pB) + { + ClanInfo cA = getClanByPlayer(pA); + ClanInfo cB = getClanByPlayer(pB); + + if (cA == null || cB == null) return true; + + return !(cA.isAlly(cB.getName()) || cA.isSelf(cB.getName())); + } + + public boolean canHurt(Player damagee, Player damager) + { + if (damagee == null || damager == null) return false; + + ClanRelation rel = relPP(damagee, damager); + + if (rel == ClanRelation.ALLY || rel == ClanRelation.ALLY_TRUST || rel == ClanRelation.SELF) return false; + + return true; + } + + public boolean isBorderlands(Location loc) + { + return (Math.abs(loc.getBlockX()) > ClansManager.CLAIMABLE_RADIUS || Math.abs(loc.getBlockZ()) > ClansManager.CLAIMABLE_RADIUS) && loc.getWorld().getName().equalsIgnoreCase("world"); + } + + /** + * Used for commands + */ + + public void join(final Player caller, final ClanInfo clanInfo) + { + if (_clansManager.getClanMemberUuidMap().containsKey(caller.getUniqueId())) + { + UtilPlayer.message(caller, F.main("Clans", "You are already in a Clan.")); + return; + } + + if (_clansManager.leftRecently(caller.getUniqueId(), 20 * 60 * 1000) != null) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot join a Clan for " + C.mTime + UtilTime.MakeStr(_clansManager.leftRecently(caller.getUniqueId(), 20 * 60 * 1000).getRight()) + C.mBody + ".")); + return; + } + + if (!_clansManager.Get(caller).canJoin()) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot join a Clan for " + C.mTime + UtilTime.convertString(System.currentTimeMillis() - _clansManager.Get(caller).getDelay(), 1, UtilTime.TimeUnit.FIT) + C.mBody + ".")); + return; + } + + if (clanInfo == null) + { + UtilPlayer.message(caller, F.main("Clans", "Error: Clan does not exist")); + return; + } + + if (!clanInfo.isInvited(caller.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You are not invited to " + F.elem("Clan " + clanInfo.getName()) + ".")); + return; + } + + if (clanInfo.getSize() >= clanInfo.getMaxSize()) + { + UtilPlayer.message(caller, F.main("Clans", "The clan " + F.elem("Clan " + clanInfo.getName()) + " is full and cannot be joined!")); + return; + } + + // Task + _clansManager.getClanDataAccess().join(clanInfo, caller, ClanRole.RECRUIT, new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + // Inform + UtilPlayer.message(caller, F.main("Clans", "You joined " + F.elem("Clan " + clanInfo.getName()) + ".")); + clanInfo.inform(F.name(caller.getName()) + " has joined your Clan.", caller.getName()); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "There was an error processing your request")); + } + } + }); + + } + + public void leave(final Player caller) + { + final ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (clan.getMembers().get(caller.getUniqueId()).getRole() == ClanRole.LEADER && clan.getMembers().size() > 1) + { + UtilPlayer.message(caller, F.main("Clans", "You must pass on " + F.elem("Leadership") + " before leaving.")); + return; + } + + // Leave or Delete + if (clan.getMembers().size() > 1) + { + // Task + _clansManager.getClanDataAccess().leave(clan, caller, new Callback() + { + @Override + public void run(Boolean data) + { + // Inform + UtilPlayer.message(caller, F.main("Clans", "You left " + F.elem("Clan " + clan.getName()) + ".")); + clan.inform(F.name(caller.getName()) + " has left your Clan.", null); + + clan.left(caller.getName()); + } + }); + } + else + { + delete(caller); + } + } + + public void delete(final Player caller) + { + final ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (getRole(caller) != ClanRole.LEADER) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader can disband the Clan.")); + return; + } + + // Event + ClanDisbandedEvent event = new ClanDisbandedEvent(clan, caller); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + _clansManager.messageClan(clan, F.main("Clans", C.cYellow + caller.getName() + C.mBody + " has disbanded the Clan.")); + + // Task + _clansManager.getClanDataAccess().delete(clan, new Callback() + { + @Override + public void run(Boolean data) + { + if (!data) + { + UtilPlayer.message(caller, F.main("Clans", "There was an error processing your request. Try again later")); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "You disbanded your Clan.")); + } + } + }); + } + + public boolean claim(Player caller) + { + ClanInfo clan = getClanByPlayer(caller); + + // Pre Event + PlayerPreClaimTerritoryEvent preEvent = new PlayerPreClaimTerritoryEvent(caller, caller.getLocation().getChunk(), clan); + + UtilServer.getServer().getPluginManager().callEvent(preEvent); + + if (preEvent.isCancelled()) + { + return false; + } + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return false; + } + + if (clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can claim Territory.")); + return false; + } + + if (_clansManager.getNetherManager().isInNether(caller)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim territory while in " + F.clansNether("The Nether") + "!")); + } + + if (!ClansManager.isClaimable(caller.getLocation())) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim territory at this location!")); + return false; + } + + if (clan.getEnergy() == 0) + { + UtilPlayer.message(caller, F.main("Clans", "You must purchase energy at a shop before you can claim land.")); + return false; + } + + ClaimLocation chunk = ClaimLocation.of(caller.getLocation().getChunk()); + ClanInfo ownerClan = getOwner(caller.getLocation()); + + // Try to Steal + if (ownerClan != null && !ownerClan.equals(clan)) + { + if (unclaimSteal(caller, clan, ownerClan)) + { + return true; + } + else + { + UtilPlayer.message(caller, F.main("Clans", "This Territory is owned by " + mRel(_clansManager.getClanUtility().relPC(caller, ownerClan), ownerClan.getName(), true) + ".")); + return false; + } + } + + if (clan.getClaims() >= clan.getClaimsMax()) + { + UtilPlayer.message(caller, F.main("Clans", "Your Clan cannot claim more Territory.")); + return false; + } + + // Adjacent + boolean selfAdj = false; + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + if ((x == 1 && z == 1) + || (x == -1 && z == 1) + || (x == -1 && z == -1) + || (x == 1 && z == -1) + || (x == 0 && z == 0)) { + continue; + } + + ClaimLocation other = ClaimLocation.of(caller.getWorld().getChunkAt(caller.getLocation().getChunk().getX() + x, caller.getLocation().getChunk().getZ() + z)); + + ClanInfo adjClan = getOwner(other); + + if (adjClan == null) continue; + + if (checkBox(caller.getWorld().getChunkAt(caller.getLocation().getChunk().getX() + x, caller.getLocation().getChunk().getZ() + z), 3)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim this Territory, it causes a box.")); + UtilPlayer.message(caller, F.main("Clans", "This means a Territory has all sides claimed.")); + return false; + } + + if (rel(clan, adjClan) == ClanRelation.SELF) + { + selfAdj = true; + } + else if (rel(clan, adjClan) != ClanRelation.SELF) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim Territory next to " + mRel(rel(ownerClan, adjClan), adjClan.getName(), true) + ".")); + return false; + } + } + } + + // Boxed + if (checkBox(caller.getLocation().getChunk(), 4)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim this Territory, it causes a box.")); + UtilPlayer.message(caller, F.main("Clans", "This means a Territory has all sides claimed.")); + return false; + } + + if (isNearAdminClaim(caller.getLocation())) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim so close to administrative territory!")); + return false; + } + + // Not Next to Self + if (!selfAdj && !clan.getClaimSet().isEmpty()) + { + UtilPlayer.message(caller, F.main("Clans", "You must claim next to your other Territory.")); + return false; + } + + // Claim Timer + if (_clansManager.getUnclaimMap().containsKey(chunk)) + { + if (!UtilTime.elapsed(_clansManager.getUnclaimMap().get(chunk), _clansManager.getReclaimTime())) + { + UtilPlayer.message(caller, F.main("Clans", "This Territory cannot be claimed for " + F.time(UtilTime.convertString(_clansManager.getReclaimTime() - (System.currentTimeMillis() - _clansManager.getUnclaimMap().get(chunk)), 1, UtilTime.TimeUnit.FIT)) + ".")); + + return false; + } + else + { + _clansManager.getUnclaimMap().remove(chunk); + } + } + + // Enemies in Land + for (Player cur : UtilServer.getPlayers()) + { + if (UtilMath.offset(cur, caller) < 16) if (playerEnemy(caller, cur)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot claim while enemies are nearby.")); + return false; + } + } + + // Recharge +// if (!Recharge.Instance.use(caller, "Territory Claim", 60000, true, false)) return false; + + // Event + PlayerClaimTerritoryEvent event = new PlayerClaimTerritoryEvent(caller, caller.getLocation().getChunk(), clan); + + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return false; + } + + // Task + _clansManager.getClanDataAccess().claim(clan.getName(), chunk, caller.getName(), false); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You claimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".")); + clan.inform(F.name(caller.getName()) + " claimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".", caller.getName()); + + return true; + } + + public boolean checkBox(Chunk chunk, int req) + { + int boxed = 0; + + // This is bad. I know. But the other way doesn't seem to work. + ClaimLocation down = ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX() + 0, chunk.getZ() + 1)); + ClaimLocation up = ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX(), chunk.getZ() - 1)); + ClaimLocation right = ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX() + 1, chunk.getZ())); + ClaimLocation left = ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX() - 1, chunk.getZ())); + + ClanInfo downClan = getOwner(down); + ClanInfo upClan = getOwner(up); + ClanInfo leftClan = getOwner(left); + ClanInfo rightClan = getOwner(right); + + if (downClan != null) boxed++; + if (upClan != null) boxed++; + if (leftClan != null) boxed++; + if (rightClan != null) boxed++; + + return (boxed >= req); + } + + public boolean unclaimSteal(Player caller, ClanInfo clientClan, ClanInfo ownerClan) + { + if (!_clansManager.canUnclaimChunk(clientClan, ownerClan)) + { + return false; + } + + // Change Inform + UtilPlayer.message(caller, F.main("Clans", "You can no longer 'steal' territory. " + "You simply unclaim it and it can not be reclaimed by anyone for 30 mintes." + "This was done to improve gameplay. Enjoy!")); + + // Inform + UtilServer.broadcast(F.main("Clans", F.elem(clientClan.getName()) + " unclaimed from " + F.elem(ownerClan.getName()) + " at " + F.elem(UtilWorld.locToStrClean(caller.getLocation())) + ".")); + + // Unclaim + _clansManager.getClanDataAccess().unclaim(ClaimLocation.of(caller.getLocation().getChunk()), caller.getName(), true); + + return true; + } + + public void promote(Player caller, String other) + { + ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + ClansPlayer self = clan.getMembers().get(caller.getUniqueId()); + + if (self.getRole().ordinal() < ClanRole.ADMIN.ordinal()) + { + UtilPlayer.message(caller, F.main("Clans", "Only Clan Admins and Leaders can promote others.")); + return; + } + + ClansPlayer target = clan.getClansPlayerFromName(other); + + if (target == null) return; + + if (target.getPlayerName().equals(caller.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot promote yourself.")); + return; + } + + if (self.getRole().ordinal() <= target.getRole().ordinal()) + { + UtilPlayer.message(caller, F.main("Clans", "You do not outrank " + F.name(other) + ".")); + return; + } + + // Task + String newRank = "?"; + if (target.getRole() == ClanRole.RECRUIT) + { + _clansManager.getClanDataAccess().role(clan, target.getUuid(), ClanRole.MEMBER); + newRank = "Member"; + } + else if (target.getRole() == ClanRole.MEMBER) + { + _clansManager.getClanDataAccess().role(clan, target.getUuid(), ClanRole.ADMIN); + newRank = "Admin"; + } + else if (target.getRole() == ClanRole.ADMIN) + { + _clansManager.getClanDataAccess().role(clan, target.getUuid(), ClanRole.LEADER); + newRank = "Leader"; + + // Give Leader + _clansManager.getClanDataAccess().role(clan, caller.getUniqueId(), ClanRole.ADMIN); + } + + // Inform + clan.inform(F.name(caller.getName()) + " promoted " + F.name(other) + " to " + F.elem(newRank) + ".", null); + } + + public void demote(Player caller, String other) + { + ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + ClansPlayer self = clan.getMembers().get(caller.getUniqueId()); + + if (self.getRole().ordinal() < ClanRole.ADMIN.ordinal()) + { + UtilPlayer.message(caller, F.main("Clans", "Only Clan Admins and Leaders can demote others.")); + return; + } + + ClansPlayer target = clan.getClansPlayerFromName(other); + + if (target == null) return; + + if (target.getPlayerName().equals(caller.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot demote yourself.")); + return; + } + + if (self.getRole().ordinal() <= target.getRole().ordinal()) + { + UtilPlayer.message(caller, F.main("Clans", "You do not outrank " + F.name(other) + ".")); + return; + } + + if (target.getRole() == ClanRole.RECRUIT) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot demote " + F.name(other) + " any further.")); + return; + } + + // Task + String newRank = "?"; + if (target.getRole() == ClanRole.MEMBER) + { + _clansManager.getClanDataAccess().role(clan, target.getUuid(), ClanRole.RECRUIT); + newRank = "Recruit"; + } + else if (target.getRole() == ClanRole.ADMIN) + { + _clansManager.getClanDataAccess().role(clan, target.getUuid(), ClanRole.MEMBER); + newRank = "Member"; + } + + // Inform + clan.inform(F.main("Clans", F.name(caller.getName()) + " demoted " + F.name(other) + " to " + F.elem(newRank) + "."), null); + } + + public void kick(final Player caller, final String other) + { + final ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + ClansPlayer self = clan.getMembers().get(caller.getUniqueId()); + ClansPlayer clansPlayer = clan.getClansPlayerFromName(other); + + if (self == null || clansPlayer == null) return; + + if (self.getRole() != ClanRole.LEADER && self.getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can kick members.")); + return; + } + + if (clansPlayer.getRole() == ClanRole.LEADER) + { + UtilPlayer.message(caller, F.main("Clans", "Clan leaders cannot be kicked.")); + UtilPlayer.message(caller, F.main("Clans", "To disband a clan, use /c disband")); + return; + } + + if ((clansPlayer.getRole() == ClanRole.LEADER && self.getRole() == ClanRole.ADMIN) || (clansPlayer.getRole() == ClanRole.ADMIN && self.getRole() == ClanRole.ADMIN)) + { + UtilPlayer.message(caller, F.main("Clans", "You do not outrank " + F.name(other) + ".")); + return; + } + + final Player player = UtilPlayer.searchOnline(null, other, false); + + Callback callback = new Callback() + { + @Override + public void run(Boolean data) + { + // Inform + if (player != null) UtilPlayer.message(player, F.main("Clans", F.name(caller.getName()) + " kicked you from " + F.elem("Clan " + clan.getName()) + ".")); + UtilPlayer.message(caller, F.main("Clans", "You kicked " + F.name(other) + " from your Clan.")); + clan.inform(F.main("Clans", F.name(caller.getName()) + " kicked " + F.name(other) + " from your Clan."), caller.getName()); + } + }; + + // Task + if (player != null) + _clansManager.getClanDataAccess().leave(clan, player, callback); + else + _clansManager.getClanDataAccess().leave(clan, clansPlayer, callback); + } + + public boolean unclaim(final Player caller, final Chunk c) + { + ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return false; + } + + ClaimLocation chunk = ClaimLocation.of(c); + ClanInfo ownerClan = getOwner(caller.getLocation()); + + // Try to Steal + if (ownerClan != null && !ownerClan.equals(clan)) if (unclaimSteal(caller, clan, ownerClan)) return true; + + // Role + if (clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can unclaim Territory.")); + return false; + } + + // Not Claimed + if (ownerClan == null || !ownerClan.equals(clan)) + { + UtilPlayer.message(caller, F.main("Clans", "This Territory is not owned by you.")); + return false; + } + + // Event + PlayerUnClaimTerritoryEvent event = new PlayerUnClaimTerritoryEvent(caller, caller.getLocation().getChunk(), ownerClan); + + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return false; + } + + // Task + _clansManager.getClanDataAccess().unclaim(chunk, caller.getName(), true); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You unclaimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".")); + clan.inform(F.name(caller.getName()) + " unclaimed Territory " + F.elem(UtilWorld.chunkToStrClean(caller.getLocation().getChunk())) + ".", caller.getName()); + + return true; + } + + public boolean unclaimAll(final Player caller) + { + ClanInfo clan = getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return false; + } + + if (clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader can unclaim all Territory.")); + return false; + } + + // Unclaim + ArrayList toUnclaim = new ArrayList<>(); + + for (ClaimLocation chunk : clan.getClaimSet()) + { + toUnclaim.add(chunk); + } + + for (ClaimLocation chunk : toUnclaim) + { + _clansManager.getClanDataAccess().unclaim(chunk, caller.getName(), true); + } + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You unclaimed all your Clans Territory.")); + clan.inform(F.name(caller.getName()) + " unclaimed all your Clans Territory.", caller.getName()); + + return true; + } + + public void invite(Player caller, ClanInfo clan, Player target) + { + if (clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can send invites.")); + return; + } + + if (target.getName().equals(caller.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot invite yourself.")); + return; + } + + if (clan.getAllies() > clan.getAlliesMaxWithMemberCountOf(clan.getSize() + 1)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot invite more members until you remove some allies.")); + return; + } + + if (clan.isInvited(target.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "Your Clan has already invited " + F.elem(target.getName()) + ".")); + return; + } + + // Inform + clan.inform(F.name(caller.getName()) + " invited " + F.name(target.getName()) + " to join your Clan.", caller.getName()); + UtilPlayer.message(caller, F.main("Clans", "You invited " + F.name(target.getName()) + " to join your Clan.")); + UtilPlayer.message(target, F.main("Clans", F.name(caller.getName()) + " invited you to join " + F.elem("Clan " + clan.getName()) + ".")); + UtilPlayer.message(target, F.main("Clans", "Type " + F.elem("/c join " + clan.getName()) + " to accept!")); + + // Task + _clansManager.getClanDataAccess().invite(clan, target.getName(), caller.getName()); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClientClan.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClientClan.java new file mode 100644 index 00000000..8ed296d5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClientClan.java @@ -0,0 +1,109 @@ +package mineplex.game.clans.clans; + +public class ClientClan +{ + private boolean _clanChat; + private boolean _allyChat; + + private boolean _mapOn; + private long _joinDelay; + + private String _territory = ""; + private boolean _autoClaim; + private String _owner = ""; + private boolean _safe; + private String _mimic = ""; + + public boolean isAllyChat() + { + return _allyChat; + } + + public void setAllyChat(boolean allyChat) + { + _allyChat = allyChat; + } + + public boolean isClanChat() + { + return _clanChat; + } + + public void setClanChat(boolean clanChat) + { + _clanChat = clanChat; + } + + public boolean isMapOn() + { + return _mapOn; + } + + public void setMapOn(boolean mapOn) + { + _mapOn = mapOn; + } + + public boolean canJoin() + { + if (System.currentTimeMillis() > _joinDelay) + return true; + + return false; + } + + public long getDelay() + { + return _joinDelay; + } + + public String getTerritory() + { + return _territory; + } + + public void setTerritory(String territory) + { + _territory = territory; + } + + public boolean isAutoClaim() + { + return _autoClaim; + } + + public String getOwner() + { + return _owner; + } + + public void setOwner(String owner) + { + _owner = owner; + } + + public boolean isSafe() + { + return _safe; + } + + public void setSafe(boolean safe) + { + _safe = safe; + } + + public void setAutoClaim(boolean autoclaim) + { + _autoClaim = autoclaim; + } + + public void setMimic(String mimic) + { + _mimic = mimic; + } + + public String getMimic() + { + return _mimic; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/HelmetPacketManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/HelmetPacketManager.java new file mode 100644 index 00000000..a32871e9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/HelmetPacketManager.java @@ -0,0 +1,112 @@ +package mineplex.game.clans.clans; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.packethandler.IPacketHandler; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment; + +/** + * Handler for custom helmet display packets + */ +public class HelmetPacketManager implements Listener +{ + private static final net.minecraft.server.v1_8_R3.ItemStack MELON = CraftItemStack.asNMSCopy(new ItemStack(Material.MELON_BLOCK)); + private static final HelmetPacketManager Instance = new HelmetPacketManager(); + + private final Map _handlers = new HashMap<>(); + + private HelmetPacketManager() + { + UtilServer.RegisterEvents(this); + } + + /** + * Fetches the registered loaded instance of this class + * @return The loaded instance of this class + */ + public static HelmetPacketManager getInstance() + { + return Instance; + } + + /** + * Sends a player helmet update to all other players + * @param player The player to update for + * @param banner The helmet to display, or null to show the player's actual helmet + */ + public void refreshToAll(Player player, ItemStack item) + { + ItemStack show = item; + + if (show == null) + { + show = new ItemStack(Material.AIR); + if (player.getInventory().getHelmet() != null) + { + show = player.getInventory().getHelmet(); + } + } + + for (Player refresh : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(refresh, new PacketPlayOutEntityEquipment(player.getEntityId(), 4, CraftItemStack.asNMSCopy(item))); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + IPacketHandler helmetHandler = (packetInfo) -> + { + if (packetInfo.getPacket() instanceof PacketPlayOutEntityEquipment) + { + PacketPlayOutEntityEquipment equip = (PacketPlayOutEntityEquipment) packetInfo.getPacket(); + + if (equip.a == player.getEntityId() && equip.b == 4) + { + ItemStack banner = UtilEnt.GetMetadata(player, "HelmetPacket.Banner"); + boolean melon = UtilEnt.hasFlag(player.getVehicle(), "HelmetPacket.RiderMelon"); + + if (banner != null) + { + equip.c = CraftItemStack.asNMSCopy(banner); + return; + } + if (melon) + { + equip.c = MELON; + return; + } + } + } + }; + + _handlers.put(event.getPlayer(), helmetHandler); + ClansManager.getInstance().getPacketHandler().addPacketHandler(helmetHandler, PacketPlayOutEntityEquipment.class); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + IPacketHandler handler = _handlers.remove(event.getPlayer()); + if (handler != null) + { + ClansManager.getInstance().getPacketHandler().removePacketHandler(handler); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/Amplifier.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/Amplifier.java new file mode 100644 index 00000000..4623bbe6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/Amplifier.java @@ -0,0 +1,47 @@ +package mineplex.game.clans.clans.amplifiers; + +import mineplex.game.clans.clans.amplifiers.AmplifierManager.AmplifierType; + +import org.bukkit.entity.Player; + +/** + * Data class for active amplifiers + */ +public class Amplifier +{ + private Player _owner; + private long _end; + + public Amplifier(Player owner, AmplifierType type) + { + _owner = owner; + _end = System.currentTimeMillis() + type.getDuration(); + } + + /** + * Gets the owner of the amplifier + * @return This amplifier's owner + */ + public Player getOwner() + { + return _owner; + } + + /** + * Gets the remaining duration of this amplifier + * @return How much time is left before this amplifier expires + */ + public long getRemainingTime() + { + return Math.max(0, _end - System.currentTimeMillis()); + } + + /** + * Checks whether this amplifier has run out of time + * @return Whether this amplifier has run out of time + */ + public boolean isEnded() + { + return System.currentTimeMillis() >= _end; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierCommand.java new file mode 100644 index 00000000..b5e14d21 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierCommand.java @@ -0,0 +1,22 @@ +package mineplex.game.clans.clans.amplifiers; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; + +/** + * Main amplifier command + */ +public class AmplifierCommand extends CommandBase +{ + public AmplifierCommand(AmplifierManager plugin) + { + super(plugin, AmplifierManager.Perm.AMPLIFIER_COMMAND, "amplifier", "runeamplifier"); + } + + @Override + public void Execute(Player caller, String[] args) + { + new AmplifierGUI(caller, Plugin); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierGUI.java new file mode 100644 index 00000000..54365b3a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierGUI.java @@ -0,0 +1,209 @@ +package mineplex.game.clans.clans.amplifiers; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.amplifiers.AmplifierManager.AmplifierType; + +/** + * GUI manager for amplifiers + */ +public class AmplifierGUI implements Listener +{ + private Player _viewer; + private AmplifierManager _manager; + private Inventory _inventory; + private final Map _items = new HashMap<>(); + private final Map _boundSlots = new HashMap<>(); + private AmplifierType _selected; + + public AmplifierGUI(Player viewer, AmplifierManager manager) + { + _viewer = viewer; + _manager = manager; + _inventory = Bukkit.createInventory(viewer, 27, C.cClansNether + "Rune Amplifiers"); + Bukkit.getPluginManager().registerEvents(this, manager.getPlugin()); + + propagate(); + open(); + } + + /** + * Gets the owner of this specific inventory + * @return The owner of this inventory + */ + public Player getViewer() + { + return _viewer; + } + + /** + * Fetches all the items registered as buttons in this inventory gui + * @return A list of the items registered as buttons in this inventory gui + */ + public Map getItems() + { + return _items; + } + + /** + * Fills the gui with buttons + */ + public void propagate() + { + getItems().clear(); + _boundSlots.clear(); + int[] slots = {12, 14}; + int i = 0; + for (AmplifierType type : AmplifierType.values()) + { + int owned = _manager.getAmountOwned(getViewer(), type); + owned = Math.max(owned, 0); + int slot = slots[i++]; + getItems().put(slot, new ItemBuilder(Material.NETHER_STAR) + .setTitle(type.getDisplayName()) + .addLore(C.cYellow + "Summons a " + C.cClansNether + "Nether Portal" + C.cYellow + " in Shops") + .addLore(C.cYellow + "And doubles the chance of Rune drops.") + .addLore(C.cRed + " ") + .addLore(C.cGreen + ">Click to Activate<") + .addLore(C.cBlue + " ") + .addLore(C.cDAqua + "You own " + F.greenElem(String.valueOf(owned)) + C.cDAqua + " " + type.getCleanDisplayName() + "s") + .build() + ); + _boundSlots.put(slot, type); + } + refresh(); + } + + /** + * Fills the confirmation menu with buttons + */ + public void propagateConfirmation() + { + getItems().clear(); + _boundSlots.clear(); + getItems().put(12, new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short) 5).setTitle(C.cGreen + "Confirm").build()); + getItems().put(14, new ItemBuilder(Material.STAINED_GLASS_PANE).setData((short) 14).setTitle(C.cRed + "Cancel").build()); + refresh(); + } + + /** + * Handles players clicking on buttons + * @param slot The slot clicked on + * @param type The type of click + */ + public void onClick(Integer slot, ClickType type) + { + if (_boundSlots.containsKey(slot)) + { + if (_manager.hasActiveAmplifier()) + { + UtilPlayer.message(getViewer(), F.main(_manager.getName(), "An amplifier is already active!")); + _manager.runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + } + else + { + _selected = _boundSlots.get(slot); + if (_manager.getAmountOwned(getViewer(), _selected) > 0) + { + propagateConfirmation(); + } + else + { + UtilPlayer.message(getViewer(), F.main(_manager.getName(), "You do not have enough of that amplifier! Purchase some at http://www.mineplex.com/shop!")); + } + } + return; + } + + if (slot == 12) + { + _manager.runSyncLater(() -> + { + _manager.useAmplifier(getViewer(), _selected); + getViewer().closeInventory(); + }, 1L); + } + if (slot == 14) + { + _selected = null; + propagate(); + } + } + + /** + * Opens this inventory to its viewer + */ + public void open() + { + _viewer.openInventory(_inventory); + } + + /** + * Updates the GUI's visuals to match registered button items + */ + public void refresh() + { + _inventory.clear(); + for (Integer slot : _items.keySet()) + { + _inventory.setItem(slot, _items.get(slot)); + } + for (Integer slot = 0; slot < _inventory.getSize(); slot++) + { + if (!_items.containsKey(slot)) + { + _inventory.setItem(slot, new ItemBuilder(Material.STAINED_GLASS_PANE).setTitle(C.cGray).setData((short)7).build()); + } + } + _viewer.updateInventory(); + } + + @EventHandler + public void handleClick(InventoryClickEvent event) + { + if (event.getClickedInventory() == null || !event.getClickedInventory().equals(_inventory)) + { + return; + } + if (!_viewer.getName().equals(event.getWhoClicked().getName())) + { + return; + } + event.setCancelled(true); + Integer slot = event.getSlot(); + if (!_items.containsKey(slot)) + { + return; + } + onClick(slot, event.getClick()); + } + + @EventHandler + public void onClose(InventoryCloseEvent event) + { + if (event.getPlayer().getUniqueId().equals(_viewer.getUniqueId())) + { + HandlerList.unregisterAll(this); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierManager.java new file mode 100644 index 00000000..ea7e5779 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/amplifiers/AmplifierManager.java @@ -0,0 +1,174 @@ +package mineplex.game.clans.clans.amplifiers; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; + +/** + * Manager for using amplifiers in clans + */ +public class AmplifierManager extends MiniPlugin +{ + public enum Perm implements Permission + { + AMPLIFIER_COMMAND, + } + + public static final double AMPLIFIER_RUNE_DROP_MULTIPLIER = 2; + private static final String AMPLIFIER_NAME = "Rune Amplifier"; + private Amplifier _active; + + public AmplifierManager(JavaPlugin plugin) + { + super("Rune Amplifiers", plugin); + + addCommand(new AmplifierCommand(this)); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.PLAYER.setPermission(Perm.AMPLIFIER_COMMAND, true, true); + } + + /** + * Checks whether there is an amplifier active on this server + * @return Whether there is an amplifier active on this server + */ + public boolean hasActiveAmplifier() + { + return _active != null; + } + + /** + * Checks how many of a certain amplifier type a player owns + * @param player The player to check + * @param type The type of amplifier to check for + * @return The amount of amplifiers of that type owned + */ + public int getAmountOwned(Player player, AmplifierType type) + { + return ClansManager.getInstance().getInventoryManager().Get(player).getItemCount(type.getFullItemName()); + } + + /** + * Makes a player use an amplifier + * @param user The player to use the amplifier + * @param type The type of amplifier to use + */ + public void useAmplifier(Player user, AmplifierType type) + { + if (getAmountOwned(user, type) < 1) + { + return; + } + if (hasActiveAmplifier()) + { + return; + } + ClansManager.getInstance().getInventoryManager().addItemToInventory(user, type.getFullItemName(), -1); + UtilTextMiddle.display(C.cClansNether + AMPLIFIER_NAME, "Has been activated by " + F.elem(user.getName())); + Bukkit.broadcastMessage(F.main(getName(), "A " + F.clansNether(AMPLIFIER_NAME) + " has been activated on this server by " + F.elem(user.getName()) + " for " + F.elem(UtilTime.MakeStr(type.getDuration())) + "!")); + _active = new Amplifier(user, type); + runSyncLater(() -> + { + ClansManager.getInstance().getNetherManager().spawnPortal(type.getDuration()); + }, 60L); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (_active != null && _active.isEnded()) + { + Bukkit.broadcastMessage(F.main(getName(), "The " + F.clansNether(AMPLIFIER_NAME) + " owned by " + F.elem(_active.getOwner().getName()) + " has run out! You can purchase another at http://www.mineplex.com/shop!")); + _active = null; + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + if (_active != null) + { + runSyncLater(() -> + { + if (_active != null) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "A " + F.clansNether(AMPLIFIER_NAME) + " owned by " + F.elem(_active.getOwner().getName()) + " is active on this server with " + F.elem(UtilTime.MakeStr(_active.getRemainingTime())) + " remaining!")); + } + }, 40L); + } + } + + /** + * Enum containing different types of amplifiers recognized by code + */ + public static enum AmplifierType + { + TWENTY("20", "Twenty Minute Amplifier", UtilTime.convert(20, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)), + SIXTY("60", "One Hour Amplifier", UtilTime.convert(60, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + + private String _extension, _display; + private long _duration; + + private AmplifierType(String extension, String displayName, long duration) + { + _extension = extension; + _display = displayName; + _duration = duration; + } + + /** + * Gets the full name of this amplifier as recognized by the inventory database + * @return The full name of this amplifier as recognized by the inventory database + */ + public String getFullItemName() + { + return AMPLIFIER_NAME + " " + _extension; + } + + /** + * Gets the display name for this amplifier in this GUI + * @return The display name for this amplifier in this GUI + */ + public String getDisplayName() + { + return C.cClansNether + _display; + } + + public String getCleanDisplayName() + { + return _display; + } + + /** + * Gets the total duration for this type of amplifier + * @return The total duration for this type of amplifier + */ + public long getDuration() + { + return _duration; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/antiafk/AfkManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/antiafk/AfkManager.java new file mode 100644 index 00000000..6425c7b4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/antiafk/AfkManager.java @@ -0,0 +1,108 @@ +package mineplex.game.clans.clans.antiafk; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.portal.GenericServer; +import mineplex.core.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; + +@ReflectivelyCreateMiniPlugin +public class AfkManager extends MiniPlugin +{ + public enum Perm implements Permission + { + BYPASS_AFK_KICK + } + + private static final long AFK_TIME_ALLOWED = UtilTime.convert(10, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); + + private AfkManager() + { + super("AFK Manager"); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.BYPASS_AFK_KICK, true, true); + PermissionGroup.YOUTUBE.setPermission(Perm.BYPASS_AFK_KICK, false, true); + PermissionGroup.TWITCH.setPermission(Perm.BYPASS_AFK_KICK, false, true); + } + + private boolean matchYawPitch(Location loc, Location loc2) + { + if (loc.getYaw() != loc2.getYaw()) + { + return false; + } + if (loc.getPitch() != loc2.getPitch()) + { + return false; + } + return true; + } + + @EventHandler + public void onMove(PlayerMoveEvent event) + { + if (UtilMath.offsetSquared(event.getFrom(), event.getTo()) > 0) + { + if (!matchYawPitch(event.getFrom(), event.getTo())) + { + UtilEnt.SetMetadata(event.getPlayer(), "AFK_MOVE", System.currentTimeMillis()); + } + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + UtilEnt.SetMetadata(event.getPlayer(), "AFK_MOVE", System.currentTimeMillis()); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC_05) + { + return; + } + Bukkit.getOnlinePlayers().forEach(player -> + { + Long lastMove = UtilEnt.GetMetadata(player, "AFK_MOVE"); + if (lastMove != null) + { + if (UtilTime.elapsed(lastMove, AFK_TIME_ALLOWED) && !ClansManager.getInstance().getClientManager().Get(player).hasPermission(Perm.BYPASS_AFK_KICK)) + { + UtilPlayer.message(player, F.main(getName(), "You have been sent to the hub for idling too long!")); + Portal.getInstance().sendPlayerToGenericServer(player, GenericServer.CLANS_HUB, Intent.KICK); + } + } + }); + } + + @EventHandler + public void onDeath(PlayerDeathEvent event) + { + runSyncLater(() -> event.getEntity().spigot().respawn(), 10); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerManager.java new file mode 100644 index 00000000..03feccf0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerManager.java @@ -0,0 +1,266 @@ +package mineplex.game.clans.clans.banners; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Banner; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +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.BannerMeta; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.command.BannerCommand; +import mineplex.game.clans.core.repository.ClanTerritory; +import net.minecraft.server.v1_8_R3.MinecraftServer; + +/** + * Manager class for cosmetic clans banners + */ +public class BannerManager extends MiniPlugin +{ + public enum Perm implements Permission + { + BANNER_COMMAND, + BANNER_ACCESS, + } + + public final Map LoadedBanners = new HashMap<>(); + private final BlockFace[] _radial = { BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST, BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST }; + private BannerRepository _repo; + + public BannerManager(JavaPlugin plugin) + { + super("Clan Banners", plugin); + _repo = new BannerRepository(plugin, this); + + addCommand(new BannerCommand(this)); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.PLAYER.setPermission(Perm.BANNER_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.BANNER_ACCESS, true, true); + } + + /** + * Checks what type of banner unlock a player has + * @param player The player to check + * @return The type of banner unlock a player has + */ + public int getBannerUnlockLevel(Player player) + { + int level = 0; + if (ClansManager.getInstance().getDonationManager().Get(player).ownsUnknownSalesPackage("Clan Banner Usage")) + { + level = 1; + } + if (ClansManager.getInstance().getDonationManager().Get(player).ownsUnknownSalesPackage("Clan Banner Editor")) + { + level = 2; + } + if (ClansManager.getInstance().getClientManager().Get(player).hasPermission(Perm.BANNER_ACCESS)) + { + level = 2; + } + return level; + } + + /** + * Loads a banner for a clan + * @param clan The clan whose banner to load + */ + public void loadBanner(ClanInfo clan) + { + _repo.loadBanner(LoadedBanners, clan); + } + + /** + * Loads all banners for this clans server + * @param manager The Clans Manager instance triggering this load + */ + public void loadBanners(ClansManager manager) + { + _repo.loadBanners(LoadedBanners, manager); + } + + /** + * Saves a banner to the database + * @param banner The banner to save + */ + public void saveBanner(ClanBanner banner) + { + _repo.saveBanner(banner); + } + + /** + * Deletes a clan's banner + * @param clan The clan whose banner to delete + */ + public void deleteBanner(ClanInfo clan) + { + _repo.deleteBanner(clan); + LoadedBanners.remove(clan.getName()); + } + + /** + * Deletes a clan banner + * @param banner The banner to delete + */ + public void deleteBanner(ClanBanner banner) + { + deleteBanner(banner.getClan()); + } + + /** + * Places a clans banner for a player + * @param placing The player who placed the banner + * @param banner The banner to place + */ + public void placeBanner(Player placing, ClanBanner banner) + { + Block block = placing.getLocation().getBlock(); + BlockPlaceEvent event = new BlockPlaceEvent(block, block.getState(), block, placing.getItemInHand(), placing, true); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) + { + ClanTerritory claim = ClansManager.getInstance().getClanUtility().getClaim(block.getLocation()); + if (claim != null && !claim.Owner.equals(banner.getClan().getName())) + { + UtilPlayer.message(placing, F.main("Clans", "You cannot place your Clan Banner there.")); + return; + } + ClansManager.getInstance().getBlockRestore().restore(block); + if (block.getType() == Material.AIR && UtilBlock.fullSolid(block.getRelative(BlockFace.DOWN))) + { + if (!Recharge.Instance.use(placing, "Place Banner", 30000, true, false)) + { + return; + } + block.setType(Material.STANDING_BANNER); + Banner state = (Banner) block.getState(); + state.setBaseColor(banner.getBaseColor()); + state.setPatterns(((BannerMeta)banner.getBanner().getItemMeta()).getPatterns()); + org.bukkit.material.Banner data = (org.bukkit.material.Banner) state.getData(); + try + { + data.setFacingDirection(_radial[Math.round(placing.getLocation().getYaw() / 45f) & 0x7]); + } + catch (Exception e) + { + e.printStackTrace(); + } + state.setData(data); + state.update(); + } + else + { + UtilPlayer.message(placing, F.main("Clans", "You cannot place your Clan Banner there.")); + return; + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBreak(BlockBreakEvent event) + { + if (event.getBlock().getType() == Material.STANDING_BANNER || event.getBlock().getType() == Material.WALL_BANNER) + { + event.setCancelled(true); + event.getBlock().setType(Material.AIR); + } + } + + @EventHandler + public void onDropBanner(BlockPhysicsEvent event) + { + if (event.getBlock().getType() == Material.STANDING_BANNER || event.getBlock().getType() == Material.WALL_BANNER) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onCraftBanner(PrepareItemCraftEvent event) + { + if (event.getInventory().getResult() == null || event.getInventory().getResult().getType() != Material.BANNER) + { + return; + } + + event.getInventory().setResult(null); + } + + @EventHandler + public void onCraftBanner(CraftItemEvent event) + { + if (event.getInventory().getResult() == null || event.getInventory().getResult().getType() != Material.BANNER) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void onJoinWithBanner(PlayerJoinEvent event) + { + if (MinecraftServer.getServer().recentTps[0] < 19) + { + return; + } + runSyncLater(() -> + { + for (ItemStack item : event.getPlayer().getInventory().getContents()) + { + if (item != null && item.getType() == Material.BANNER) + { + event.getPlayer().getInventory().remove(item); + } + } + }, 20); + } + + @EventHandler + public void onPickupBanner(PlayerPickupItemEvent event) + { + if (event.getItem().getItemStack().getType() == Material.BANNER) + { + event.setCancelled(true); + event.getItem().remove(); + } + } + + @EventHandler + public void onPickupBanner(PlayerDropItemEvent event) + { + if (event.getItemDrop().getItemStack().getType() == Material.BANNER) + { + event.getItemDrop().remove(); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerPattern.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerPattern.java new file mode 100644 index 00000000..62cc5ec3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerPattern.java @@ -0,0 +1,84 @@ +package mineplex.game.clans.clans.banners; + +import org.bukkit.DyeColor; +import org.bukkit.block.banner.Pattern; +import org.bukkit.block.banner.PatternType; + +/** + * Data class for clans banner patterns + */ +public class BannerPattern +{ + private int _layer; + private DyeColor _color; + private PatternType _type; + + public BannerPattern(int layer, DyeColor color, PatternType type) + { + _layer = layer; + _color = color; + _type = type; + } + + public BannerPattern(int layer) + { + _layer = layer; + _color = null; + _type = null; + } + + /** + * Gets the layer this pattern occupies on the clan's banner + * @return The layer this pattern occupies on the clan's banner + */ + public int getLayer() + { + return _layer; + } + + /** + * Gets the Bukkit version of this banner pattern + * @return The Bukkit version of this banner pattern, or null if this is not a fully configured pattern + */ + public Pattern getBukkitPattern() + { + if (_color == null || _type == null) + { + return null; + } + + return new Pattern(_color, _type); + } + + /** + * Gets the form this banner pattern will take in the database + * @return The form this banner pattern will take in the database + */ + public String getDatabaseForm() + { + if (_color == null || _type == null) + { + return "Blank"; + } + + return _color.toString() + "," + _type.toString(); + } + + /** + * Sets the color of this banner pattern + * @param color The color to set this pattern to + */ + public void setColor(DyeColor color) + { + _color = color; + } + + /** + * Sets the design of this banner pattern + * @param color The design to set this pattern to + */ + public void setPatternType(PatternType type) + { + _type = type; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerRepository.java new file mode 100644 index 00000000..8d236bcd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/BannerRepository.java @@ -0,0 +1,166 @@ +package mineplex.game.clans.clans.banners; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.bukkit.DyeColor; +import org.bukkit.block.banner.PatternType; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.database.MinecraftRepository; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +/** + * Database repository class for banners + */ +public class BannerRepository extends RepositoryBase +{ + private static final String CREATE = "CREATE TABLE IF NOT EXISTS clanBanners (clanId INT NOT NULL," + + "baseColor VARCHAR(15)," + + "patterns VARCHAR(300)," + + "PRIMARY KEY (clanId));"; + + private static final String GET_BANNER_BY_CLAN = "SELECT * FROM clanBanners WHERE clanId=? LIMIT 1;"; + private static final String GET_BANNERS_BY_SERVER = "SELECT clans.name, clanBanners.baseColor, clanBanners.patterns FROM clans INNER JOIN clanBanners ON clans.id=clanBanners.clanId AND clans.serverId=?;"; + private static final String INSERT_BANNER = "INSERT INTO clanBanners (clanId, baseColor, patterns) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE baseColor=VALUES(baseColor), patterns=VALUES(patterns);"; + private static final String DELETE_BANNER = "DELETE FROM clanBanners WHERE clanId=?;"; + + private BannerManager _bannerManager; + + public BannerRepository(JavaPlugin plugin, BannerManager bannerManager) + { + super(DBPool.getAccount()); + _bannerManager = bannerManager; + } + + /** + * Loads a banner for a certain clan into a given hashmap + * @param map The hashmap to load the banner into + * @param clan The clan whose banner to fetch + */ + public void loadBanner(final Map map, ClanInfo clan) + { + _bannerManager.runAsync(() -> + { + executeQuery(GET_BANNER_BY_CLAN, resultSet -> + { + while(resultSet.next()) + { + DyeColor baseColor = DyeColor.valueOf(resultSet.getString("baseColor")); + List patternStrs = Arrays.asList(resultSet.getString("patterns").split("/")); + LinkedList patterns = new LinkedList<>(); + int layer = 1; + for (String patternStr : patternStrs) + { + if (patternStr.equalsIgnoreCase("Blank")) + { + patterns.add(new BannerPattern(layer)); + } + else + { + try + { + DyeColor patternColor = DyeColor.valueOf(patternStr.split(",")[0]); + PatternType patternType = PatternType.valueOf(patternStr.split(",")[1]); + patterns.add(new BannerPattern(layer, patternColor, patternType)); + } + catch (Exception e) + { + e.printStackTrace(); + patterns.add(new BannerPattern(layer)); + } + } + layer++; + } + map.put(clan.getName(), new ClanBanner(_bannerManager, clan, baseColor, patterns)); + } + }, new ColumnInt("clanId", clan.getId())); + }); + } + + /** + * Loads all banners for a certain clans server into a given hashmap + * @param map The hashmap to load the banner into + * @param clan The clan whose banner to fetch + */ + public void loadBanners(final Map map, ClansManager clanManager) + { + _bannerManager.runAsync(() -> + { + executeQuery(GET_BANNERS_BY_SERVER, resultSet -> + { + while(resultSet.next()) + { + String clanName = resultSet.getString("name"); + DyeColor baseColor = DyeColor.valueOf(resultSet.getString("baseColor")); + List patternStrs = Arrays.asList(resultSet.getString("patterns").split("/")); + LinkedList patterns = new LinkedList<>(); + int layer = 1; + for (String patternStr : patternStrs) + { + if (patternStr.equalsIgnoreCase("Blank")) + { + patterns.add(new BannerPattern(layer)); + } + else + { + try + { + DyeColor patternColor = DyeColor.valueOf(patternStr.split(",")[0]); + PatternType patternType = PatternType.valueOf(patternStr.split(",")[1]); + patterns.add(new BannerPattern(layer, patternColor, patternType)); + } + catch (Exception e) + { + e.printStackTrace(); + patterns.add(new BannerPattern(layer)); + } + } + layer++; + } + map.put(clanName, new ClanBanner(_bannerManager, clanManager.getClanMap().get(clanName), baseColor, patterns)); + } + }, new ColumnInt("serverId", clanManager.getServerId())); + }); + } + + /** + * Saves a banner into the database + * @param banner The banner to save + */ + public void saveBanner(ClanBanner banner) + { + _bannerManager.runAsync(() -> + { + String patternStr = ""; + for (BannerPattern pattern : banner.getPatterns()) + { + if (!patternStr.equalsIgnoreCase("")) + { + patternStr = patternStr + "/"; + } + patternStr = patternStr + pattern.getDatabaseForm(); + } + executeUpdate(INSERT_BANNER, new ColumnInt("clanId", banner.getClan().getId()), new ColumnVarChar("baseColor", 15, banner.getBaseColor().toString()), new ColumnVarChar("patterns", 300, patternStr)); + }); + } + + /** + * Deletes a banner from the database + * @param clan The clan whose banner to delete + */ + public void deleteBanner(ClanInfo clan) + { + _bannerManager.runAsync(() -> + { + executeUpdate(DELETE_BANNER, new ColumnInt("clanId", clan.getId())); + }); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/ClanBanner.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/ClanBanner.java new file mode 100644 index 00000000..5a12ab68 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/ClanBanner.java @@ -0,0 +1,113 @@ +package mineplex.game.clans.clans.banners; + +import java.util.LinkedList; +import java.util.List; + +import mineplex.core.common.util.C; +import mineplex.game.clans.clans.ClanInfo; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.block.banner.Pattern; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BannerMeta; + +import com.google.common.collect.Lists; + +/** + * Data class for clan banners + */ +public class ClanBanner +{ + private BannerManager _manager; + private ClanInfo _clan; + private DyeColor _baseColor; + private LinkedList _patterns; + + public ClanBanner(BannerManager manager, ClanInfo clan, DyeColor baseColor, LinkedList patterns) + { + _manager = manager; + _clan = clan; + _baseColor = baseColor; + _patterns = patterns; + } + + /** + * Gets the clan that owns this banner + * @return The clan that owns this banner + */ + public ClanInfo getClan() + { + return _clan; + } + + /** + * Gets the base color for this banner + * @return The base color for this banner + */ + public DyeColor getBaseColor() + { + return _baseColor; + } + + /** + * Gets this banner's patterns + * @return This banner's patterns + */ + public LinkedList getPatterns() + { + return _patterns; + } + + /** + * Gets the ItemStack representation of this banner + * @return The ItemStack representation of this banner + */ + public ItemStack getBanner() + { + ItemStack banner = new ItemStack(Material.BANNER); + BannerMeta im = (BannerMeta) banner.getItemMeta(); + + im.setDisplayName(C.cGray + _clan.getName() + "'s Banner"); + im.setBaseColor(_baseColor); + List patterns = Lists.newArrayList(); + for (BannerPattern bp : _patterns) + { + if (bp.getBukkitPattern() != null) + { + patterns.add(bp.getBukkitPattern()); + } + } + im.setPatterns(patterns); + banner.setItemMeta(im); + + return banner; + } + + /** + * Sets the base color of this banner + * @param color The color to set + */ + public void setBaseColor(DyeColor color) + { + _baseColor = color; + } + + /** + * Saves this banner to the database + */ + public void save() + { + _manager.saveBanner(this); + } + + /** + * Places this banner on the ground + * @param player The player to place the banner for + */ + public void place(Player player) + { + _manager.placeBanner(player, this); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/command/BannerCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/command/BannerCommand.java new file mode 100644 index 00000000..10c11772 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/command/BannerCommand.java @@ -0,0 +1,65 @@ +package mineplex.game.clans.clans.banners.command; + +import java.util.LinkedList; + +import org.bukkit.DyeColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.BannerManager; +import mineplex.game.clans.clans.banners.BannerPattern; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.banners.gui.nonedit.NonEditOverviewGUI; + +/** + * Main banner usage command + */ +public class BannerCommand extends CommandBase +{ + public BannerCommand(BannerManager plugin) + { + super(plugin, BannerManager.Perm.BANNER_COMMAND, "banner"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (ClansManager.getInstance().getClan(caller) == null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not in a Clan!")); + return; + } + ClanInfo clan = ClansManager.getInstance().getClan(caller); + + if (Plugin.getBannerUnlockLevel(caller) < 1) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "You have not purchased the ability to use Clan banners! Buy it at http://www.mineplex.com/shop!")); + return; + } + if (!Plugin.LoadedBanners.containsKey(clan.getName())) + { + if (Plugin.getBannerUnlockLevel(caller) >= 2 && clan.getMembers().get(caller.getUniqueId()).getRole() == ClanRole.LEADER) + { + LinkedList patterns = new LinkedList<>(); + for (int i = 0; i < 12; i++) + { + patterns.add(new BannerPattern(i + 1)); + } + ClanBanner banner = new ClanBanner(Plugin, clan, DyeColor.WHITE, patterns); + Plugin.LoadedBanners.put(clan.getName(), banner); + banner.save(); + } + else + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Your Clan does not have a set banner!")); + return; + } + } + new NonEditOverviewGUI(caller, Plugin.LoadedBanners.get(clan.getName())); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/BannerGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/BannerGUI.java new file mode 100644 index 00000000..0c6b5e68 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/BannerGUI.java @@ -0,0 +1,123 @@ +package mineplex.game.clans.clans.banners.gui; + +import java.util.HashMap; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +/** + * Base class to manage banner guis + */ +public abstract class BannerGUI implements Listener +{ + private Player _viewer; + private Inventory _inventory; + private final HashMap _items = new HashMap<>(); + + public BannerGUI(Player viewer, String pageName, int slots) + { + _viewer = viewer; + _inventory = Bukkit.createInventory(viewer, slots, pageName); + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + } + + /** + * Gets the owner of this specific inventory + * @return The owner of this inventory + */ + public Player getViewer() + { + return _viewer; + } + + /** + * Fetches all the items registered as buttons in this inventory gui + * @return A list of the items registered as buttons in this inventory gui + */ + public HashMap getItems() + { + return _items; + } + + /** + * Fills the gui with buttons + */ + public abstract void propagate(); + + /** + * Handles players clicking on buttons + * @param slot The slot clicked on + * @param type The type of click + */ + public abstract void onClick(Integer slot, ClickType type); + + /** + * Opens this inventory to its viewer + */ + public void open() + { + _viewer.openInventory(_inventory); + } + + /** + * Updates the GUI's visuals to match registered button items + */ + public void refresh() + { + _inventory.clear(); + for (Integer slot : _items.keySet()) + { + _inventory.setItem(slot, _items.get(slot)); + } + for (Integer slot = 0; slot < _inventory.getSize(); slot++) + { + if (!_items.containsKey(slot)) + { + _inventory.setItem(slot, new ItemBuilder(Material.STAINED_GLASS_PANE).setTitle(C.cGray).setData((short)7).build()); + } + } + _viewer.updateInventory(); + } + + @EventHandler + public void handleClick(InventoryClickEvent event) + { + if (event.getClickedInventory() == null || !event.getClickedInventory().equals(_inventory)) + { + return; + } + if (!_viewer.getName().equals(event.getWhoClicked().getName())) + { + return; + } + event.setCancelled(true); + Integer slot = event.getSlot(); + if (!_items.containsKey(slot)) + { + return; + } + onClick(slot, event.getClick()); + } + + @EventHandler + public void onClose(InventoryCloseEvent event) + { + if (event.getPlayer().getUniqueId().equals(_viewer.getUniqueId())) + { + HandlerList.unregisterAll(this); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/BaseColorSelectionGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/BaseColorSelectionGUI.java new file mode 100644 index 00000000..cc3a93bf --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/BaseColorSelectionGUI.java @@ -0,0 +1,78 @@ +package mineplex.game.clans.clans.banners.gui.creation; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.banners.gui.BannerGUI; +import mineplex.game.clans.clans.banners.gui.overview.OverviewGUI; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +/** + * GUI manager for selecting a banner's base color + */ +public class BaseColorSelectionGUI extends BannerGUI +{ + private ClanBanner _banner; + + public BaseColorSelectionGUI(Player viewer, ClanBanner banner) + { + super(viewer, "Background Color", 27); + _banner = banner; + + propagate(); + open(); + } + + @Override + public void propagate() + { + Integer slot = 1; + for (short data = 0; data <= 15; data++) + { + getItems().put(slot, new ItemBuilder(Material.INK_SACK).setData(data).setTitle(C.cGray).build()); + if ((slot + 1) == 8) + { + slot = 10; + } + else if ((slot + 1) == 17) + { + slot = 21; + } + else if ((slot + 1) == 22) + { + slot = 23; + } + else + { + slot++; + } + } + refresh(); + } + + @SuppressWarnings("deprecation") + @Override + public void onClick(Integer slot, ClickType type) + { + if (getItems().get(slot).getType() == Material.INK_SACK) + { + DyeColor color = DyeColor.getByDyeData(getItems().get(slot).getData().getData()); + _banner.setBaseColor(color); + _banner.save(); + + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new OverviewGUI(getViewer(), _banner); + }, 2L); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/PatternColorSelectionGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/PatternColorSelectionGUI.java new file mode 100644 index 00000000..3daef4b6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/PatternColorSelectionGUI.java @@ -0,0 +1,80 @@ +package mineplex.game.clans.clans.banners.gui.creation; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.BannerPattern; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.banners.gui.BannerGUI; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +/** + * GUI manager for selecting a banner pattern's base color + */ +public class PatternColorSelectionGUI extends BannerGUI +{ + private ClanBanner _banner; + private int _bannerPos; + + public PatternColorSelectionGUI(Player viewer, ClanBanner banner, int bannerPosition) + { + super(viewer, "Pattern Color", 27); + _banner = banner; + _bannerPos = bannerPosition; + + propagate(); + open(); + } + + @Override + public void propagate() + { + Integer slot = 1; + for (short data = 0; data <= 15; data++) + { + getItems().put(slot, new ItemBuilder(Material.INK_SACK).setData(data).setTitle(C.cGray).build()); + if ((slot + 1) == 8) + { + slot = 10; + } + else if ((slot + 1) == 17) + { + slot = 21; + } + else if ((slot + 1) == 22) + { + slot = 23; + } + else + { + slot++; + } + } + refresh(); + } + + @SuppressWarnings("deprecation") + @Override + public void onClick(Integer slot, ClickType type) + { + if (getItems().get(slot).getType() == Material.INK_SACK) + { + DyeColor color = DyeColor.getByDyeData(getItems().get(slot).getData().getData()); + BannerPattern pattern = _banner.getPatterns().get(_bannerPos); + pattern.setColor(color); + + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new PatternTypeSelectionGUI(getViewer(), _banner, _bannerPos, color); + }, 2L); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/PatternTypeSelectionGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/PatternTypeSelectionGUI.java new file mode 100644 index 00000000..587d0dea --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/creation/PatternTypeSelectionGUI.java @@ -0,0 +1,87 @@ +package mineplex.game.clans.clans.banners.gui.creation; + +import java.util.LinkedList; + +import mineplex.core.common.util.C; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.BannerPattern; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.banners.gui.BannerGUI; +import mineplex.game.clans.clans.banners.gui.overview.OverviewGUI; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.block.banner.Pattern; +import org.bukkit.block.banner.PatternType; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BannerMeta; + +/** + * GUI manager for selecting a banner pattern's design + */ +public class PatternTypeSelectionGUI extends BannerGUI +{ + private ClanBanner _banner; + private int _bannerPos; + private DyeColor _color; + + public PatternTypeSelectionGUI(Player viewer, ClanBanner banner, int bannerPosition, DyeColor patternColor) + { + super(viewer, "Pattern Color", 45); + _banner = banner; + _bannerPos = bannerPosition; + _color = patternColor; + + propagate(); + open(); + } + + @Override + public void propagate() + { + for (int i = 0; i < PatternType.values().length; i++) + { + ItemStack item = new ItemStack(Material.BANNER); + BannerMeta im = (BannerMeta) item.getItemMeta(); + im.setBaseColor(_banner.getBaseColor()); + LinkedList patterns = new LinkedList<>(); + for (int patternId = 0; patternId < _bannerPos; patternId++) + { + BannerPattern show = _banner.getPatterns().get(patternId); + if (show.getBukkitPattern() != null) + { + patterns.add(show.getBukkitPattern()); + } + } + patterns.add(new Pattern(_color, PatternType.values()[i])); + im.setPatterns(patterns); + im.setDisplayName(C.cGray); + item.setItemMeta(im); + getItems().put(i, item); + } + refresh(); + } + + @Override + public void onClick(Integer slot, ClickType ctype) + { + if (getItems().get(slot).getType() == Material.BANNER) + { + PatternType type = ((BannerMeta)getItems().get(slot).getItemMeta()).getPatterns().get(Math.min(_bannerPos, ((BannerMeta)getItems().get(slot).getItemMeta()).getPatterns().size() - 1)).getPattern(); + BannerPattern pattern = _banner.getPatterns().get(_bannerPos); + pattern.setPatternType(type); + _banner.save(); + + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new OverviewGUI(getViewer(), _banner); + }, 2L); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/nonedit/NonEditOverviewGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/nonedit/NonEditOverviewGUI.java new file mode 100644 index 00000000..812236bc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/nonedit/NonEditOverviewGUI.java @@ -0,0 +1,94 @@ +package mineplex.game.clans.clans.banners.gui.nonedit; + +import java.util.Arrays; + +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.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.HelmetPacketManager; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.banners.gui.BannerGUI; +import mineplex.game.clans.clans.banners.gui.overview.OverviewGUI; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +/** + * GUI manager for viewing a banner usage overview + */ +public class NonEditOverviewGUI extends BannerGUI +{ + private ClanBanner _banner; + + public NonEditOverviewGUI(Player viewer, ClanBanner banner) + { + super(viewer, "Clan Banner", 9); + _banner = banner; + + propagate(); + open(); + } + + @Override + public void propagate() + { + ItemStack banner = _banner.getBanner().clone(); + ItemMeta im = banner.getItemMeta(); + im.setDisplayName(C.cGreen + "Clan Banner"); + im.setLore(Arrays.asList(new String[] {F.elem("Left Click") + " to toggle wearing your banner", F.elem("Right Click") + " to place down your banner"})); + banner.setItemMeta(im); + getItems().put(4, banner); + + if (_banner.getClan().getMembers().get(getViewer().getUniqueId()).getRole() == ClanRole.LEADER && ClansManager.getInstance().getBannerManager().getBannerUnlockLevel(getViewer()) >= 2) + { + getItems().put(8, new ItemBuilder(Material.ANVIL).setTitle(C.cGold + "Edit Your Banner").build()); + } + refresh(); + } + + @Override + public void onClick(Integer slot, ClickType type) + { + if (slot == 4) + { + if (type == ClickType.LEFT) + { + if (UtilEnt.GetMetadata(getViewer(), "HelmetPacket.Banner") != null) + { + UtilEnt.removeMetadata(getViewer(), "HelmetPacket.Banner"); + HelmetPacketManager.getInstance().refreshToAll(getViewer(), null); + UtilPlayer.message(getViewer(), F.main("Clan Banners", "You have removed your banner!")); + } + else + { + ItemStack banner = _banner.getBanner(); + UtilEnt.SetMetadata(getViewer(), "HelmetPacket.Banner", banner); + HelmetPacketManager.getInstance().refreshToAll(getViewer(), banner); + UtilPlayer.message(getViewer(), F.main("Clan Banners", "You have donned your banner!")); + } + } + else if (type == ClickType.RIGHT) + { + _banner.place(getViewer()); + } + } + if (slot == 8) + { + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new OverviewGUI(getViewer(), _banner); + }, 2L); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/overview/OverviewGUI.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/overview/OverviewGUI.java new file mode 100644 index 00000000..a60ba188 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/banners/gui/overview/OverviewGUI.java @@ -0,0 +1,124 @@ +package mineplex.game.clans.clans.banners.gui.overview; + +import java.util.Arrays; + +import mineplex.core.common.util.C; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.BannerPattern; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.banners.gui.BannerGUI; +import mineplex.game.clans.clans.banners.gui.creation.BaseColorSelectionGUI; +import mineplex.game.clans.clans.banners.gui.creation.PatternColorSelectionGUI; +import mineplex.game.clans.clans.banners.gui.nonedit.NonEditOverviewGUI; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BannerMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.material.MaterialData; + +/** + * GUI manager for overviewing a banner's design + */ +public class OverviewGUI extends BannerGUI +{ + private static final int MAX_BANNER_LAYERS = 12; + private static final int PATTERN_DISPLAY_START_SLOT = 27; + private final ClanBanner _banner; + + public OverviewGUI(Player viewer, ClanBanner banner) + { + super(viewer, "Clan Banner", 45); + _banner = banner; + + propagate(); + open(); + } + + @Override + @SuppressWarnings("deprecation") + public void propagate() + { + getItems().put(4, _banner.getBanner()); + ItemStack color = new MaterialData(Material.INK_SACK, _banner.getBaseColor().getDyeData()).toItemStack(1); + ItemMeta colorMeta = color.getItemMeta(); + colorMeta.setDisplayName(C.cGray); + color.setItemMeta(colorMeta); + getItems().put(22, color); + Integer slot = PATTERN_DISPLAY_START_SLOT; + for (int i = 0; i < MAX_BANNER_LAYERS; i++) + { + ItemStack item = new ItemStack(Material.INK_SACK, 1, (short)8); + if (i < _banner.getPatterns().size()) + { + BannerPattern pattern = _banner.getPatterns().get(i); + if (pattern.getBukkitPattern() != null) + { + ItemStack representation = new ItemStack(Material.BANNER); + BannerMeta im = (BannerMeta) representation.getItemMeta(); + im.setBaseColor(_banner.getBaseColor()); + im.setDisplayName(C.cGray); + im.setPatterns(Arrays.asList(pattern.getBukkitPattern())); + representation.setItemMeta(im); + item = representation; + } + } + getItems().put(slot, item); + slot++; + } + refresh(); + } + + @Override + public void onClick(Integer slot, ClickType type) + { + if (slot == 4) + { + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new NonEditOverviewGUI(getViewer(), _banner); + }, 2L); + } + if (slot == 22) + { + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new BaseColorSelectionGUI(getViewer(), _banner); + }, 2L); + } + if (slot >= PATTERN_DISPLAY_START_SLOT) + { + if (type == ClickType.RIGHT) + { + _banner.getPatterns().get(slot - PATTERN_DISPLAY_START_SLOT).setColor(null); + ClansManager.getInstance().runSyncLater(() -> + { + getItems().clear(); + propagate(); + refresh(); + }, 1L); + } + else + { + ClansManager.getInstance().runSyncLater(() -> + { + getViewer().closeInventory(); + }, 1L); + ClansManager.getInstance().runSyncLater(() -> + { + new PatternColorSelectionGUI(getViewer(), _banner, slot - PATTERN_DISPLAY_START_SLOT); + }, 2L); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/bosstoken/BossTokenPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/bosstoken/BossTokenPage.java new file mode 100644 index 00000000..64a1c966 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/bosstoken/BossTokenPage.java @@ -0,0 +1,113 @@ +package mineplex.game.clans.clans.bosstoken; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.WorldEventType; + +public class BossTokenPage extends ShopPageBase +{ + public BossTokenPage(WorldEventManager plugin, BossTokenShop shop, String name, Player player) + { + super(plugin, shop, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), name, player, 27); + + buildPage(); + } + + @Override + protected void buildPage() + { + int[] slots = {12, 14}; + int i = 0; + for (TokenType type : TokenType.values()) + { + int owned = ClansManager.getInstance().getInventoryManager().Get(_player).getItemCount(type.getItemName()); + int slot = slots[i++]; + addButton(slot, type.getButton(C.cRed + type.getDisplay() + " Summon Token", Arrays.asList( + C.cYellow + "Summon the powerful " + type.getDisplay(), + C.cYellow + "In the " + C.cRed + "Borderlands", + C.cRed + " ", + C.cGreen + ">Click to Activate<", + C.cBlue + " ", + C.cDAqua + "You own " + F.greenElem(String.valueOf(Math.max(owned, 0))) + C.cDAqua + " " + type.getDisplay() + " Summon Tokens" + ) + ), (player, clickType) -> + { + if (!Recharge.Instance.use(player, "Clans Box Click", 1000, false, false)) + { + return; + } + if (owned < 1) + { + playDenySound(player); + UtilPlayer.message(player, F.main(getPlugin().getName(), "You do not have enough of that token! Purchase some at http://www.mineplex.com/shop!")); + return; + } + if (!getPlugin().getEvents().isEmpty()) + { + playDenySound(player); + UtilPlayer.message(player, F.main(getPlugin().getName(), "There is already an ongoing event! Try again later!")); + return; + } + WorldEventManager manager = getPlugin(); + player.closeInventory(); + manager.startEventFromType(type.getType()); + ClansManager.getInstance().getInventoryManager().addItemToInventory(player, type.getItemName(), -1); + }); + } + } + + private enum TokenType + { + SKELETON("Skeleton", "Skeleton King", WorldEventType.SKELETON_KING, (name, lore) -> new ItemBuilder(Material.SKULL_ITEM).setData((short)1).setTitle(name).addLores(lore).build()), + WIZARD("Wizard", "Iron Wizard", WorldEventType.IRON_WIZARD, SkinData.IRON_GOLEM::getSkull) + ; + + private final String _itemEnding; + private final String _display; + private final WorldEventType _type; + private final BiFunction, ItemStack> _buttonCreator; + + private TokenType(String itemEnding, String display, WorldEventType type, BiFunction, ItemStack> buttonCreator) + { + _itemEnding = itemEnding; + _display = display; + _type = type; + _buttonCreator = buttonCreator; + } + + public String getItemName() + { + return "Clans Boss Token " + _itemEnding; + } + + public String getDisplay() + { + return _display; + } + + public WorldEventType getType() + { + return _type; + } + + public ItemStack getButton(String itemName, List lore) + { + return _buttonCreator.apply(itemName, lore); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/bosstoken/BossTokenShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/bosstoken/BossTokenShop.java new file mode 100644 index 00000000..9f4a5179 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/bosstoken/BossTokenShop.java @@ -0,0 +1,22 @@ +package mineplex.game.clans.clans.bosstoken; + +import org.bukkit.entity.Player; + +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; + +public class BossTokenShop extends ShopBase +{ + public BossTokenShop(WorldEventManager plugin) + { + super(plugin, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), "Boss Token"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new BossTokenPage(getPlugin(), this, "Boss Tokens", player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/BoxManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/BoxManager.java new file mode 100644 index 00000000..9c77b83b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/BoxManager.java @@ -0,0 +1,217 @@ +package mineplex.game.clans.clans.boxes; + +import java.util.function.Consumer; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.boxes.extra.BuilderBox; + +public class BoxManager extends MiniPlugin +{ + private final BoxShop _shop; + + public BoxManager(JavaPlugin plugin) + { + super("Box Manager", plugin); + + _shop = new BoxShop(this); + } + + public void openDyePage(Player player) + { + _shop.attemptShopOpen(player); + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onCraftWithDye(PrepareItemCraftEvent event) + { + if (event.getInventory().getResult() == null) + { + return; + } + if (event.getInventory().getResult().getType() == Material.LAPIS_BLOCK) + { + for (ItemStack item : event.getInventory().getMatrix()) + { + if (item == null) + { + continue; + } + if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equals(C.cGold + "Dye")) + { + event.getInventory().setResult(null); + return; + } + } + return; + } + if (event.getInventory().getResult().getType() == Material.INK_SACK) + { + event.getInventory().setResult(null); + return; + } + for (ItemStack item : event.getInventory().getMatrix()) + { + if (item == null) + { + continue; + } + if (item.getType() != Material.INK_SACK) + { + continue; + } + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !item.getItemMeta().getDisplayName().equals(C.cGold + "Dye")) + { + event.getInventory().setResult(null); + } + } + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onCraftWithDye(CraftItemEvent event) + { + if (event.getInventory().getResult() == null) + { + return; + } + if (event.getInventory().getResult().getType() == Material.LAPIS_BLOCK) + { + for (ItemStack item : event.getInventory().getMatrix()) + { + if (item == null) + { + continue; + } + if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equals(C.cGold + "Dye")) + { + event.setCancelled(true); + return; + } + } + return; + } + if (event.getInventory().getResult().getType() == Material.INK_SACK) + { + event.setCancelled(true); + return; + } + for (ItemStack item : event.getInventory().getMatrix()) + { + if (item == null) + { + continue; + } + if (item.getType() != Material.INK_SACK) + { + continue; + } + if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !item.getItemMeta().getDisplayName().equals(C.cGold + "Dye")) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onPlaceDyeInAnvil(InventoryClickEvent event) + { + if (!(event.getWhoClicked() instanceof Player)) + { + return; + } + if (!event.getInventory().getType().equals(InventoryType.ANVIL)) + { + return; + } + if (!(event.getCursor() != null && event.getCursor().hasItemMeta() && event.getCursor().getItemMeta().hasDisplayName() && event.getCursor().getItemMeta().getDisplayName().equals(C.cGold + "Dye")) && !(event.getCurrentItem() != null && event.getCurrentItem().hasItemMeta() && event.getCurrentItem().getItemMeta().hasDisplayName() && event.getCurrentItem().getItemMeta().getDisplayName().equals(C.cGold + "Dye"))) + { + return; + } + event.setCancelled(true); + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (event.getItem() == null || !event.getItem().hasItemMeta() || !event.getItem().getItemMeta().hasDisplayName()) + { + return; + } + if (event.getItem().getItemMeta().getDisplayName().equals(C.cGold + "Dye")) + { + event.setCancelled(true); + } + } + + public static enum BoxType + { + BUILDER_BOX("Clans Builder Box", C.cGold + "Builder's Box", Material.GLOWSTONE, BuilderBox::open), + @SuppressWarnings("deprecation") + DYE_BOX(null, C.cGreen + "Dye Box", Material.INK_SACK, DyeColor.RED.getDyeData(), Managers.get(BoxManager.class)::openDyePage), + ; + + private String _itemName, _displayName; + private ItemBuilder _displayBuilder; + private Consumer _itemGenerator; + + private BoxType(String itemName, String displayName, Material displayMaterial, Consumer itemGenerator) + { + _itemName = itemName; + _displayName = displayName; + _displayBuilder = new ItemBuilder(displayMaterial).setTitle(displayName).addLore(C.cRed); + _itemGenerator = itemGenerator; + } + + private BoxType(String itemName, String displayName, Material displayMaterial, short data, Consumer itemGenerator) + { + _itemName = itemName; + _displayName = displayName; + _displayBuilder = new ItemBuilder(displayMaterial).setData(data).setTitle(displayName).addLore(C.cRed); + _itemGenerator = itemGenerator; + } + + public String getItemName() + { + return _itemName; + } + + public String getDisplayName() + { + return _displayName; + } + + public ItemStack getDisplayItem(int owned) + { + ItemBuilder newBuilder = new ItemBuilder(_displayBuilder.build()); + if (owned == -1) + { + return newBuilder.build(); + } + if (owned > 0) + { + newBuilder.setGlow(true); + } + return newBuilder.addLore(C.cGreenB + "Owned: " + C.cWhite + owned).build(); + } + + public void onUse(Player player) + { + _itemGenerator.accept(player); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/BoxShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/BoxShop.java new file mode 100644 index 00000000..d91caafb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/BoxShop.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.clans.boxes; + +import org.bukkit.entity.Player; + +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class BoxShop extends ShopBase +{ + public BoxShop(BoxManager plugin) + { + super(plugin, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), "Boxes"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new DyeBoxPage(getPlugin(), this, "Dye Boxes", player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/DyeBoxPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/DyeBoxPage.java new file mode 100644 index 00000000..8d62274e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/DyeBoxPage.java @@ -0,0 +1,107 @@ +package mineplex.game.clans.clans.boxes; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class DyeBoxPage extends ShopPageBase +{ + private static final List COMMON_COLORS = Stream.of(DyeColor.values()).filter(c -> c != DyeColor.BLACK && c != DyeColor.WHITE).collect(Collectors.toList()); + private static final List RARE_COLORS = Arrays.asList(DyeColor.WHITE, DyeColor.BLACK); + + public DyeBoxPage(BoxManager plugin, BoxShop shop, String name, Player player) + { + super(plugin, shop, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), name, player, 27); + + buildPage(); + } + + @SuppressWarnings("deprecation") + @Override + protected void buildPage() + { + int[] slots = {12, 14}; + int i = 0; + for (DyeType type : DyeType.values()) + { + int owned = ClansManager.getInstance().getInventoryManager().Get(_player).getItemCount(type.getItemName()); + int slot = slots[i++]; + addButton(slot, SkinData.CLANS_DYE_BOX.getSkull(C.cRed + (type.isGilded() ? "Gilded " : "") + "Dye Box", Arrays.asList( + C.cYellow + "Open a box containing " + F.greenElem(String.valueOf(type.getDyeCount())) + C.cYellow + " random dyes!", + C.cRed + " ", + C.cGreen + ">Click to Activate<", + C.cBlue + " ", + C.cDAqua + "You own " + F.greenElem(String.valueOf(Math.max(owned, 0))) + C.cDAqua + (type.isGilded() ? " Gilded" : "") + " Dye Boxes")), + (player, clickType) -> + { + if (!Recharge.Instance.use(player, "Clans Box Click", 1000, false, false)) + { + return; + } + if (owned < 1) + { + playDenySound(player); + UtilPlayer.message(player, F.main(getPlugin().getName(), "You do not have enough of that box! Purchase some at http://www.mineplex.com/shop!")); + return; + } + player.closeInventory(); + ClansManager.getInstance().getInventoryManager().addItemToInventory(player, type.getItemName(), -1); + for (int dye = 0; dye < type.getDyeCount(); dye++) + { + List options = ThreadLocalRandom.current().nextDouble() <= 0.05 ? RARE_COLORS : COMMON_COLORS; + DyeColor color = UtilMath.randomElement(options); + player.getInventory().addItem(new ItemBuilder(Material.INK_SACK).setData(color.getDyeData()).setTitle(C.cGold + "Dye").build()); + } + }); + } + } + + private enum DyeType + { + NORMAL("Clans Dye Box", false, 32), + GILDED("Clans Gilded Dye Box", true, 64) + ; + + private final String _itemName; + private final boolean _gilded; + private final int _dyeCount; + + private DyeType(String itemName, boolean gilded, int dyeCount) + { + _itemName = itemName; + _gilded = gilded; + _dyeCount = dyeCount; + } + + public String getItemName() + { + return _itemName; + } + + public boolean isGilded() + { + return _gilded; + } + + public int getDyeCount() + { + return _dyeCount; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/extra/BuilderBox.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/extra/BuilderBox.java new file mode 100644 index 00000000..8fc831ca --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/boxes/extra/BuilderBox.java @@ -0,0 +1,106 @@ +package mineplex.game.clans.clans.boxes.extra; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.boxes.BoxManager.BoxType; + +public class BuilderBox +{ + private static final Map, ItemStack> REPLACEMENT_ITEMS; + + static + { + Map, ItemStack> replacements = new HashMap<>(); + replacements.put(Pair.create(Material.STONE, (byte)0), new ItemStack(Material.STAINED_CLAY)); + replacements.put(Pair.create(Material.GLASS, (byte)0), new ItemStack(Material.STAINED_GLASS)); + replacements.put(Pair.create(Material.THIN_GLASS, (byte)0), new ItemStack(Material.STAINED_GLASS_PANE)); + replacements.put(Pair.create(Material.WOOL, (byte)0), new ItemStack(Material.WOOL)); + replacements.put(Pair.create(Material.CARPET, (byte)0), new ItemStack(Material.CARPET)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)0), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)1), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)2), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)3), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)4), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)5), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)6), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)7), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.RED_ROSE, (byte)8), new ItemStack(Material.RED_ROSE)); + replacements.put(Pair.create(Material.COBBLE_WALL, (byte)0), new ItemStack(Material.COBBLE_WALL)); + replacements.put(Pair.create(Material.JACK_O_LANTERN, (byte)0), new ItemStack(Material.GLOWSTONE)); + replacements.put(Pair.create(Material.SMOOTH_BRICK, (byte)0), new ItemStack(Material.SMOOTH_BRICK)); + + REPLACEMENT_ITEMS = Collections.unmodifiableMap(replacements); + } + + @SuppressWarnings("deprecation") + private static ItemStack convert(ItemStack old) + { + if (old == null) + { + return null; + } + Pair pair = Pair.create(old.getType(), old.getData().getData()); + if (!REPLACEMENT_ITEMS.containsKey(pair)) + { + return null; + } + ItemBuilder after = new ItemBuilder(REPLACEMENT_ITEMS.get(pair)); + if (after.getType() == Material.RED_ROSE) + { + after.setData((short)UtilMath.r(9)); + } + else if (after.getType() == Material.COBBLE_WALL) + { + after.setData((short)1); + } + else if (after.getType() == Material.GLOWSTONE) + { + after.setData((short)0); + } + else if (after.getType() == Material.SMOOTH_BRICK) + { + after.setData(UtilMath.randomElement(new Short[] {1, 3})); + } + else + { + after.setData(UtilMath.randomElement(DyeColor.values()).getWoolData()); + } + after.setAmount(old.getAmount()); + + return after.build(); + } + + public static void open(Player player) + { + boolean used = false; + for (int i = 0; i < player.getInventory().getSize(); i++) + { + ItemStack converted = convert(player.getInventory().getItem(i)); + if (converted == null) + { + continue; + } + used = true; + player.getInventory().setItem(i, converted); + } + + if (used) + { + ClansManager.getInstance().getInventoryManager().addItemToInventory(player, BoxType.BUILDER_BOX.getItemName(), -1); + UtilPlayer.message(player, F.main("Builder's Box", "You have redeemed your box contents!")); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashOverviewPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashOverviewPage.java new file mode 100644 index 00000000..598d6046 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashOverviewPage.java @@ -0,0 +1,177 @@ +package mineplex.game.clans.clans.cash; + +import java.lang.reflect.Field; +import java.util.Arrays; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.inventory.Inventory; + +import mineplex.core.Managers; +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.inventory.ClientInventory; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.shop.confirmation.ConfirmationCallback; +import mineplex.core.shop.confirmation.ConfirmationPage; +import mineplex.core.shop.confirmation.ConfirmationProcessor; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.amplifiers.AmplifierGUI; +import mineplex.game.clans.clans.boxes.BoxManager; +import mineplex.game.clans.clans.boxes.BoxManager.BoxType; +import mineplex.game.clans.clans.supplydrop.SupplyDropManager; + +public class CashOverviewPage extends ShopPageBase +{ + private static final int OVERVIEW_BUTTON_SLOT = 13; + private static final int RUNE_BUTTON_SLOT = 21; + private static final int BUILDERS_BUTTON_SLOT = 23; + private static final int SUPPLY_BUTTON_SLOT = 29; + private static final int DYE_BUTTON_SLOT = 31; + private static final int BOSS_BUTTON_SLOT = 33; + private static final int MOUNT_BUTTON_SLOT = 39; + private static final int BANNER_BUTTON_SLOT = 41; + + public CashOverviewPage(CashShopManager plugin, CashShop shop, String name, Player player) + { + super(plugin, shop, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), name, player); + + buildPage(); + } + + @Override + protected void buildPage() + { + ClientInventory inv = ClansManager.getInstance().getInventoryManager().Get(getPlayer()); + int rune20 = inv.getItemCount("Rune Amplifier 20"); + int rune60 = inv.getItemCount("Rune Amplifier 60"); + int builders = inv.getItemCount(BoxType.BUILDER_BOX.getItemName()); + int supply = inv.getItemCount("Clans Supply Drop"); + int supplyGilded = inv.getItemCount("Clans Gilded Supply Drop"); + int dye = inv.getItemCount("Clans Dye Box"); + int dyeGilded = inv.getItemCount("Clans Gilded Dye Box"); + int skeleton = inv.getItemCount("Clans Boss Token Skeleton"); + int wizard = inv.getItemCount("Clans Boss Token Wizard"); + addButtonNoAction(OVERVIEW_BUTTON_SLOT, new ItemBuilder(Material.EMERALD) + .setTitle(C.cRed + C.Scramble + "1 " + C.cRed + "Mineplex Shop" + " " + C.Scramble + "1") + .addLore(C.cYellow + "Purchase powerful supply drops, boss summoning items,") + .addLore(C.cYellow + "and exclusive cosmetic items in our online store!") + .addLore(C.cRed + " ") + .addLore(C.cGreen + "http://www.mineplex.com/shop") + .build() + ); + addButton(RUNE_BUTTON_SLOT, new ItemBuilder(Material.NETHER_STAR) + .setTitle(C.cRed + "Rune Amplifier") + .addLore(C.cYellow + "Open a portal to the Nether in Shops") + .addLore(C.cYellow + "And double the chances for Rune drops!") + .addLore(C.cRed + " ") + .addLore(C.cDAqua + "You own " + F.greenElem(String.valueOf(rune20)) + C.cDAqua + " Twenty Minute Amplifiers") + .addLore(C.cDAqua + "You own " + F.greenElem(String.valueOf(rune60)) + C.cDAqua + " One Hour Amplifiers") + .build(), + (player, clickType) -> + { + player.closeInventory(); + new AmplifierGUI(player, ClansManager.getInstance().getAmplifierManager()); + }); + addButton(BUILDERS_BUTTON_SLOT, SkinData.CLANS_BUILDERS_BOX.getSkull(C.cRed + "Builder's Box", Arrays.asList( + C.cYellow + "Transform normal blocks into alternate forms", + C.cYellow + "Or otherwise unobtainable cosmetic blocks!", + C.cRed + " ", + C.cDAqua + "You own " + F.greenElem(String.valueOf(builders)) + C.cDAqua + " Builder's Boxes")), + (player, clickType) -> + { + if (builders < 1) + { + return; + } + getShop().openPageForPlayer(player, new ConfirmationPage<>(player, this, new ConfirmationProcessor() + { + @Override + public void init(Inventory inventory) + { + try + { + Field returnPage = ConfirmationPage.class.getDeclaredField("_returnPage"); + returnPage.setAccessible(true); + returnPage.set(inventory, null); + returnPage.setAccessible(false); + } + catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) + { + e.printStackTrace(); + } + } + + @Override + public void process(ConfirmationCallback callback) + { + BoxType.BUILDER_BOX.onUse(player); + callback.resolve("Opening Builder's Box..."); + } + }, SkinData.CLANS_BUILDERS_BOX.getSkull(C.cRed + "Open Builder's Box", UtilText.splitLines(new String[] + { + C.cRed, + C.cRedB + "WARNING: " + C.cWhite + "This will convert all applicable items in your inventory!" + }, LineFormat.LORE)), "Confirm Opening Box")); + }); + addButton(SUPPLY_BUTTON_SLOT, SkinData.CLANS_GILDED_SUPPLY_DROP.getSkull(C.cRed + "Supply Drop", Arrays.asList( + C.cYellow + "Call down Supply Drops to obtain", + C.cYellow + "Rare and valuable resources!", + C.cRed + " ", + C.cYellow + "Use " + C.cGreen + "/inventory" + C.cYellow + " to access Supply Drops", + C.cBlue + " ", + C.cDAqua + "You own " + F.greenElem(String.valueOf(supply)) + C.cDAqua + " Supply Drops", + C.cDAqua + "You own " + F.greenElem(String.valueOf(supplyGilded)) + C.cDAqua + " Gilded Supply Drops")), + (player, clickType) -> + { + player.closeInventory(); + Managers.get(SupplyDropManager.class).getShop().attemptShopOpen(player); + }); + addButton(DYE_BUTTON_SLOT, SkinData.CLANS_DYE_BOX.getSkull(C.cRed + "Dye Box", Arrays.asList( + C.cYellow + "Open a box containing a large amount", + C.cYellow + "Of different dyes to use!", + C.cRed + " ", + C.cDAqua + "You own " + F.greenElem(String.valueOf(dye)) + C.cDAqua + " Dye Boxes", + C.cDAqua + "You own " + F.greenElem(String.valueOf(dyeGilded)) + C.cDAqua + " Gilded Dye Boxes")), + (player, clickType) -> + { + player.closeInventory(); + Managers.get(BoxManager.class).openDyePage(player); + }); + addButton(BOSS_BUTTON_SLOT, new ItemBuilder(Material.GOLD_INGOT) + .setTitle(C.cRed + "Boss Summon Token") + .addLore(C.cYellow + "Summon powerful World Bosses to fight") + .addLore(C.cYellow + "Whenever you are most prepared!") + .addLore(C.cRed + " ") + .addLore(C.cYellow + "Use " + C.cGreen + "/inventory" + C.cYellow + " to access Boss Summon Tokens") + .addLore(C.cBlue + " ") + .addLore(C.cDAqua + "You own " + F.greenElem(String.valueOf(skeleton)) + C.cDAqua + " Skeleton King Tokens") + .addLore(C.cDAqua + "You own " + F.greenElem(String.valueOf(wizard)) + C.cDAqua + " Iron Wizard Tokens") + .build(), + (player, clickType) -> + { + player.closeInventory(); + ClansManager.getInstance().getWorldEvent().getShop().attemptShopOpen(player); + }); + addButtonNoAction(MOUNT_BUTTON_SLOT, new ItemBuilder(Material.DIAMOND_BARDING) + .setTitle(C.cRed + "Mount Skins") + .addLore(C.cYellow + "Stroll around the map in style!") + .build() + ); + addButton(BANNER_BUTTON_SLOT, new ItemBuilder(Material.BANNER) + .setTitle(C.cRed + "Clan Banner") + .addLore(C.cYellow + "Show off your Clan Pride!") + .build(), + (player, clickType) -> + { + player.closeInventory(); + UtilServer.CallEvent(new PlayerCommandPreprocessEvent(player, "/banner")); + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashShop.java new file mode 100644 index 00000000..2d08ae96 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashShop.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.clans.cash; + +import org.bukkit.entity.Player; + +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class CashShop extends ShopBase +{ + public CashShop(CashShopManager manager) + { + super(manager, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), "Online Store"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new CashOverviewPage(getPlugin(), this, "Online Store", player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashShopManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashShopManager.java new file mode 100644 index 00000000..8095713e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/cash/CashShopManager.java @@ -0,0 +1,42 @@ +package mineplex.game.clans.clans.cash; + +import org.bukkit.entity.Player; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.command.CommandBase; + +@ReflectivelyCreateMiniPlugin +public class CashShopManager extends MiniPlugin +{ + public enum Perm implements Permission + { + INVENTORY_COMMAND_PERMISSION, + } + + private final CashShop _shop; + + private CashShopManager() + { + super("Online Store"); + + _shop = new CashShop(this); + + addCommand(new CommandBase(this, Perm.INVENTORY_COMMAND_PERMISSION, "inventory") + { + public void Execute(Player caller, String[] args) + { + _shop.attemptShopOpen(caller); + } + }); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.PLAYER.setPermission(Perm.INVENTORY_COMMAND_PERMISSION, true, true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/ClaimVisualizer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/ClaimVisualizer.java new file mode 100644 index 00000000..8f347b8a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/ClaimVisualizer.java @@ -0,0 +1,366 @@ +package mineplex.game.clans.clans.claimview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.minecraft.server.v1_8_R3.EnumDirection; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.claimview.commands.ClaimVisualizeCommand; +import mineplex.game.clans.clans.event.ClanDisbandedEvent; +import mineplex.game.clans.clans.event.ClanLeaveEvent; +import mineplex.game.clans.clans.event.PlayerUnClaimTerritoryEvent; +import mineplex.game.clans.core.ClaimLocation; + +public class ClaimVisualizer extends MiniPlugin +{ + public enum Perm implements Permission + { + VISUALIZE_COMMAND, + } + + private ClansManager _clansManager; + + private List _visualizing; + + private NautHashMap> _calculated; + + public ClaimVisualizer(JavaPlugin plugin, ClansManager clansManager) + { + super("Claim Visualizer", plugin); + + _clansManager = clansManager; + _visualizing = new ArrayList<>(); + _calculated = new NautHashMap<>(); + + for (ClanInfo clan : _clansManager.getClanMap().values()) + { + _calculated.put(clan, new NautHashMap<>()); + } + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.PLAYER.setPermission(Perm.VISUALIZE_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new ClaimVisualizeCommand(this)); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOWER) + { + return; + } + + _calculated.clear(); + for (ClanInfo clan : _clansManager.getClanMap().values()) + { + _calculated.put(clan, new NautHashMap<>()); + + for (ClaimLocation chunk : clan.getClaimSet()) + { + calculate(clan, chunk); + } + } + } + + @EventHandler + public void runVisualization(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + for (String name : _visualizing) + { + Player player = Bukkit.getPlayer(name); + + if (player != null && _clansManager.isInClan(player)) + { + visualize(player); + } + } + } + + private void visualize(Player player) + { + for (ClaimLocation claim : _clansManager.getClan(player).getClaimSet()) + { + if (!_calculated.get(_clansManager.getClan(player)).containsKey(claim)) + { + calculate(_clansManager.getClan(player), claim); + } + } + + draw(player, _calculated.get(_clansManager.getClan(player)).values()); + } + + private void draw(Player player, Collection chunks) + { + for (VisualizedChunkData chunk : chunks) + { + if (!chunk.getChunk().getWorld().equals(player.getWorld())) + { + // return not break because a clan can't have claims in different worlds. + return; + } + + if (UtilMath.offset2d(chunk.getChunk().getBlock(0, 0, 0).getLocation(), player.getLocation()) > 36) + { + break; + } + + for (int x = 0; x < 16; x++) + { + for (int z = 0; z < 16; z++) + { + if (chunk.shouldDisplayEdge(x, z) && (z == 0 || z == 15 || x == 0 || x == 15)) + { + Block block = chunk.getChunk().getBlock(x, 0, z); + + UtilParticle.PlayParticle(ParticleType.RED_DUST, + new Location( + chunk.getChunk().getWorld(), + block.getX() + .5, + UtilBlock.getHighest(player.getWorld(), block.getX(), block.getZ()).getY() + .5, + block.getZ() + .5), + new Vector(0f, 0f, 0f), 0f, 1, ViewDist.NORMAL, player); + } + } + } + } + } + + private void calculate(ClanInfo clan, ClaimLocation claim) + { + Chunk chunk = claim.toChunk(); + + List dirs = new ArrayList<>(); + + if (!clan.getClaimSet().contains(ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX(), chunk.getZ() - 1)))) + { + dirs.add(EnumDirection.NORTH); + } + + if (!clan.getClaimSet().contains(ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX() + 1, chunk.getZ())))) + { + dirs.add(EnumDirection.EAST); + } + + if (!clan.getClaimSet().contains(ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX(), chunk.getZ() + 1)))) + { + dirs.add(EnumDirection.SOUTH); + } + + if (!clan.getClaimSet().contains(ClaimLocation.of(chunk.getWorld().getChunkAt(chunk.getX() - 1, chunk.getZ())))) + { + dirs.add(EnumDirection.WEST); + } + + VisualizedChunkData cached = new VisualizedChunkData(chunk, dirs); + + _calculated.get(clan).put(claim, cached); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + if (isVisualizing(event.getPlayer())) + { + disableVisualizer(event.getPlayer()); + } + } + + @EventHandler + public void onKick(PlayerKickEvent event) + { + if (isVisualizing(event.getPlayer())) + { + disableVisualizer(event.getPlayer()); + } + } + + @EventHandler + public void onLeave(ClanLeaveEvent event) + { + if (isVisualizing(event.getPlayer().getPlayerName())) + { + disableVisualizer(event.getPlayer().getPlayerName()); + } + } + + @EventHandler + public void onClanDisband(ClanDisbandedEvent event) + { + for (Player player : event.getClan().getOnlinePlayers()) + { + if (isVisualizing(player)) + { + disableVisualizer(player); + } + } + } + + @EventHandler + public void update(ClanInfo clan) + { + _calculated.clear(); + + for (ClaimLocation claim : clan.getClaimSet()) + { + calculate(clan, claim); + } + } + + @EventHandler + public void onUnclaim(PlayerUnClaimTerritoryEvent event) + { + if (event.getClan().getClaimCount() == 1) + { + for (Player player : event.getClan().getOnlinePlayers()) + { + if (isVisualizing(player)) + { + disableVisualizer(player); + } + } + } + } + + public boolean isVisualizing(Player player) + { + return _visualizing.contains(player.getName()); + } + + public boolean isVisualizing(String name) + { + return _visualizing.contains(name); + } + + public void enableVisualizer(String name) + { + enableVisualizer(UtilServer.getServer().getPlayer(name)); + } + + public void disableVisualizer(String name) + { + disableVisualizer(UtilServer.getServer().getPlayer(name)); + } + + public void toggleVisualizer(Player player) + { + if (_visualizing.contains(player.getName())) + { + disableVisualizer(player); + } + else + { + enableVisualizer(player); + } + } + + public void enableVisualizer(Player player) + { + if (player == null) + { + return; + } + + if (!_clansManager.isInClan(player)) + { + UtilPlayer.message(player, F.main("Clans", "You must be in a clan to visualize claims.")); + return; + } + + ClanInfo clan = _clansManager.getClan(player); + + if (clan.getClaimCount() == 0) + { + UtilPlayer.message(player, F.main("Clans", "Your Clan does not have any claims!")); + return; + } + + _visualizing.add(player.getName()); + UtilPlayer.message(player, F.main("Clans", "You are now visualizing your claims.")); + + for (VisualizedChunkData chunk : _calculated.get(clan).values()) + { + if (!chunk.getChunk().getWorld().equals(player.getWorld())) + { + // return not break because a clan can't have claims in different worlds. + return; + } + + if (UtilMath.offset2d(chunk.getChunk().getBlock(0, 0, 0).getLocation(), player.getLocation()) > 36) + { + break; + } + + for (int x = 0; x < 16; x++) + { + for (int z = 0; z < 16; z++) + { + if (chunk.shouldDisplayEdge(x, z) && (z == 0 || z == 15 || x == 0 || x == 15)) + { + Block block = chunk.getChunk().getBlock(x, 0, z); + } + } + } + } + } + + public void disableVisualizer(Player player) + { + if (player == null) + { + return; + } + + if (!_visualizing.contains(player.getName())) + { + UtilPlayer.message(player, F.main("Clans", "You are anot visualizing your claims.")); + return; + } + + _visualizing.remove(player.getName()); + UtilPlayer.message(player, F.main("Clans", "You are no longer visualizing your claims.")); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/VisualizedChunkData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/VisualizedChunkData.java new file mode 100644 index 00000000..1427f20a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/VisualizedChunkData.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.clans.claimview; + +import java.util.List; + +import org.bukkit.Chunk; + +import net.minecraft.server.v1_8_R3.EnumDirection; + +public class VisualizedChunkData +{ + private List _displayableEdges; + private Chunk _chunk; + + public long _start; + + public VisualizedChunkData(Chunk chunk, List dir) + { + _chunk = chunk; + _displayableEdges = dir; + _start = System.currentTimeMillis(); + } + + public double getLife() + { + return (double) (System.currentTimeMillis() - _start); + } + + public boolean shouldDisplayEdge(int x, int z) + { + if (z == 15 && !_displayableEdges.contains(EnumDirection.SOUTH)) + { + return false; + } + + if (x == 15 && !_displayableEdges.contains(EnumDirection.EAST)) + { + return false; + } + + if (x == 0 && !_displayableEdges.contains(EnumDirection.WEST)) + { + return false; + } + + if (z == 0 && !_displayableEdges.contains(EnumDirection.NORTH)) + { + return false; + } + + return true; + } + + public Chunk getChunk() + { + return _chunk; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/commands/ClaimVisualizeCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/commands/ClaimVisualizeCommand.java new file mode 100644 index 00000000..15d60a15 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/claimview/commands/ClaimVisualizeCommand.java @@ -0,0 +1,20 @@ +package mineplex.game.clans.clans.claimview.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.clans.claimview.ClaimVisualizer; + +public class ClaimVisualizeCommand extends CommandBase +{ + public ClaimVisualizeCommand(ClaimVisualizer plugin) + { + super(plugin, ClaimVisualizer.Perm.VISUALIZE_COMMAND, "showclaims"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.toggleVisualizer(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansAllyChatCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansAllyChatCommand.java new file mode 100644 index 00000000..e0cf3191 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansAllyChatCommand.java @@ -0,0 +1,56 @@ +package mineplex.game.clans.clans.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.punish.Punish; +import mineplex.core.punish.PunishClient; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; + +public class ClansAllyChatCommand extends CommandBase +{ + public ClansAllyChatCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.ALLY_CHAT_COMMAND, "ac"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length == 0) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + } + else + { + Plugin.Get(caller).setAllyChat(!Plugin.Get(caller).isAllyChat()); + UtilPlayer.message(caller, F.main("Clans", "Ally Chat: " + F.oo(Plugin.Get(caller).isAllyChat()))); + } + return; + } + + //Single Clan + if (!Plugin.Get(caller).isAllyChat()) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + if (clan == null) UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + else + { + PunishClient punishClient = Managers.get(Punish.class).GetClient(caller.getName()); + if (punishClient != null && punishClient.IsMuted()) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot do this while muted!")); + return; + } + Plugin.chatAlly(clan, caller, F.combine(args, 0, null, false)); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansChatCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansChatCommand.java new file mode 100644 index 00000000..29b3e5e8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansChatCommand.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.clans.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.punish.Punish; +import mineplex.core.punish.PunishClient; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; + +public class ClansChatCommand extends CommandBase +{ + public ClansChatCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.CLAN_CHAT_COMMAND, "cc", "fc"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length == 0) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + } + else + { + Plugin.Get(caller).setClanChat(!Plugin.Get(caller).isClanChat()); + UtilPlayer.message(caller, F.main("Clans", "Clan Chat: " + F.oo(Plugin.Get(caller).isClanChat()))); + } + return; + } + + //Single Clan + if (!Plugin.Get(caller).isClanChat()) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + if (clan == null) + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + else + { + PunishClient punishClient = Managers.get(Punish.class).GetClient(caller.getName()); + if (punishClient != null && punishClient.IsMuted()) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot do this while muted!")); + return; + } + Plugin.chatClan(clan, caller, F.combine(args, 0, null, false)); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java new file mode 100644 index 00000000..d74dc20d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java @@ -0,0 +1,1195 @@ +package mineplex.game.clans.clans.commands; + +import java.util.Collections; +import java.util.List; + +import net.minecraft.server.v1_8_R3.EnumDirection; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import com.google.common.collect.Lists; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilInput; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilPlayerBase; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.delayedtask.DelayedTask; +import mineplex.core.delayedtask.DelayedTaskClient; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClientClan; +import mineplex.game.clans.clans.event.ClanJoinEvent; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.spawn.Spawn; + +public class ClansCommand extends CommandBase +{ + private ClansManager _clansManager; + + public ClansCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.CLANS_COMMAND, "c", "clan", "clans", "factions"); + + _clansManager = plugin; + } + + @Override + public void Execute(Player caller, String[] args) + { + if (UtilServer.CallEvent(new ClansCommandPreExecutedEvent(caller, args)).isCancelled()) + return; + + if (args == null || args.length == 0) + { + _clansManager.getClanShop().attemptShopOpen(caller); + return; + } + + if (args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("h")) + help(caller); + + else if (args[0].equalsIgnoreCase("admin") || args[0].equalsIgnoreCase("x")) + Plugin.getClanAdmin().command(caller, args); + + else if (args[0].equalsIgnoreCase("create")) + create(caller, args); + + else if (args[0].equalsIgnoreCase("disband") || args[0].equalsIgnoreCase("delete")) + delete(caller, args); + + else if (args[0].equalsIgnoreCase("invite") || args[0].equalsIgnoreCase("i")) + invite(caller, args); + + else if (args[0].equalsIgnoreCase("promote") || args[0].equalsIgnoreCase("+")) + promote(caller, args); + else if (args[0].equalsIgnoreCase("forcejoin") || args[0].equalsIgnoreCase("fj")) + forceJoin(caller, args); + else if (args[0].equalsIgnoreCase("demote") || args[0].equalsIgnoreCase("-")) + demote(caller, args); + + else if (args[0].equalsIgnoreCase("join") || args[0].equalsIgnoreCase("j")) + join(caller, args); + + else if (args[0].equalsIgnoreCase("leave") || args[0].equalsIgnoreCase("l")) + leave(caller, args); + + else if (args[0].equalsIgnoreCase("kick") || args[0].equalsIgnoreCase("k")) + kick(caller, args); + + else if (args[0].equalsIgnoreCase("ally") || args[0].equalsIgnoreCase("a")) + ally(caller, args); + +// else if (args[0].equalsIgnoreCase("trust")) +// trust(caller, args); + + else if (args[0].equalsIgnoreCase("neutral") || args[0].equalsIgnoreCase("neut") || args[0].equalsIgnoreCase("n")) + neutral(caller, args); + + else if (args[0].equalsIgnoreCase("claim") || args[0].equalsIgnoreCase("c")) + claim(caller, args); + + else if (args[0].equalsIgnoreCase("unclaim") || args[0].equalsIgnoreCase("uc")) + unclaim(caller, args); + else if (args[0].equalsIgnoreCase("home") || args[0].equalsIgnoreCase("h")) + home(caller, args); + + else if (args[0].equalsIgnoreCase("sethome")) + homeSet(caller); + else if (args[0].equalsIgnoreCase("stuck")) + stuck(caller); + + /* + * else if (args[0].equalsIgnoreCase("enemy") || args[0].equals("e")) + * enemy(caller, args); + */ + + else if (args[0].equalsIgnoreCase("who") || args[0].equalsIgnoreCase("w")) + { + if (args.length > 1) + infoClan(caller, args[1]); + else + infoClan(caller, null); + } + else + infoClan(caller, args[0]); + } + + private void forceJoin(Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "forcejoin", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + if (!Plugin.getClientManager().Get(caller).hasPermission(ClansManager.Perm.FORCE_JOIN_COMMAND)) + { + UtilPlayerBase.message(caller, C.mHead + "Permissions> " + C.mBody + "You do not have permission to do that."); + return; + } + + if (args.length > 1) + { + ClanInfo clan = Plugin.getClan(args[1]); + + if (clan != null) + { + _clansManager.getClanUtility().join(caller, clan); + _clansManager.getClanDataAccess().role(clan, caller.getUniqueId(), ClanRole.LEADER); + UtilPlayer.message(caller, F.main("Clans", "You have successfully joined " + F.elem(clan.getName()) + " and are now Leader Role.")); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "Clan provided does not exist.")); + } + } + else + { + UtilPlayer.message(caller, F.main("Clans", "No clan provided.")); + } + } + + public void commandChat(Player caller, String[] args) + { + if (args.length == 0) + { + Plugin.Get(caller).setClanChat(!Plugin.Get(caller).isClanChat()); + UtilPlayer.message(caller, F.main("Clans", "Clan Chat: " + F.oo(Plugin.Get(caller).isClanChat()))); + return; + } + + // Single Clan + if (!Plugin.Get(caller).isClanChat()) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + if (clan == null) + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + else + Plugin.chatClan(clan, caller, F.combine(args, 0, null, false)); + } + } + + public void commandAllyChat(Player caller, String[] args) + { + if (args.length == 0) + { + Plugin.Get(caller).setAllyChat(!Plugin.Get(caller).isAllyChat()); + UtilPlayer.message(caller, F.main("Clans", "Ally Chat: " + F.oo(Plugin.Get(caller).isAllyChat()))); + return; + } + + // Single Clan + if (!Plugin.Get(caller).isAllyChat()) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + if (clan == null) + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + else + Plugin.chatAlly(clan, caller, F.combine(args, 0, null, false)); + } + } + + private void help(Player caller) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "help"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + UtilPlayer.message(caller, F.main("Clans", "Commands List;")); + UtilPlayer.message(caller, F.help("/c create ", "Create new Clan", ChatColor.WHITE)); + UtilPlayer.message(caller, F.help("/c join ", "Join a Clan", ChatColor.WHITE)); + UtilPlayer.message(caller, F.help("/c leave ", "Leave your Clan", ChatColor.WHITE)); + UtilPlayer.message(caller, F.help("/cc (Message)", "Clan Chat (Toggle)", ChatColor.WHITE)); + + UtilPlayer.message(caller, F.help("/c stuck", "Teleports you to the nearest Wilderness location", ChatColor.WHITE)); + + UtilPlayer.message(caller, F.help("/c promote ", "Promote Player in Clan", ChatColor.GOLD)); + UtilPlayer.message(caller, F.help("/c demote ", "Demote Player in Clan", ChatColor.GOLD)); + + UtilPlayer.message(caller, F.help("/c home (set)", "Teleport to Clan Home", ChatColor.GOLD)); + + UtilPlayer.message(caller, F.help("/c invite ", "Invite Player to Clan", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/c kick ", "Kick Player from Clan", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/c neutral ", "Request Neutrality with Clan", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/c enemy ", "Declare ClanWar with Clan", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/c ally ", "Send Alliance to Clan", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/c claim", "Claim Territory", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/c unclaim (all)", "Unclaim Territory", ChatColor.DARK_RED)); + + UtilPlayer.message(caller, F.help("/c delete", "Delete your Clan", ChatColor.DARK_RED)); + + UtilPlayer.message(caller, F.help("/c ", "View Clan Information", ChatColor.WHITE)); + } + + public void create(final Player caller, final String[] args) + { +// System.out.println("CREATE COMMAND"); + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "create", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClientClan client = Plugin.Get(caller); + + if (Plugin.getClanMemberUuidMap().containsKey(caller.getUniqueId())) + { + UtilPlayer.message(caller, F.main("Clans", "You are already in a Clan.")); + return; + } + + if (Plugin.leftRecently(caller.getUniqueId(), 5 * 60 * 1000) != null) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot create a Clan for " + C.mTime + UtilTime.MakeStr(Plugin.leftRecently(caller.getUniqueId(), 20 * 60 * 1000).getRight()) + C.mBody + ".")); + return; + } + + /* + * TODO if (!client.canJoin()) { _manager.getTutorials().sendTutorialMsg(caller, + * F.main("Clans", "You cannot join a Clan for " + C.mTime + + * UtilTime.convertString(System.currentTimeMillis() - + * client.getDelay(), 1, TimeUnit.FIT) + C.mBody + ".")); return; } + */ + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a Clan name.")); + return; + } + + if (!UtilInput.valid(args[1])) + { + UtilPlayer.message(caller, F.main("Clans", "Invalid characters in Clan name.")); + return; + } + + if (args[1].length() < Plugin.getNameMin()) + { + UtilPlayer.message(caller, F.main("Clans", "Clan name too short. Minimum length is " + (Plugin.getNameMin()) + ".")); + return; + } + + if (args[1].length() > Plugin.getNameMax()) + { + UtilPlayer.message(caller, F.main("Clans", "Clan name too long. Maximum length is " + (Plugin.getNameMax()) + ".")); + return; + } + + if (Plugin.getChat().filterMessage(caller, args[1]).contains("*")) + { + UtilPlayer.message(caller, F.main("Clans", "Clan name inappropriate. Please try a different name")); + return; + } + + if (!Plugin.getBlacklist().allowed(args[1])) + { + UtilPlayer.message(caller, F.main("Clans", "Clan name is blacklisted! Please try a different name.")); + return; + } + + Plugin.getClanDataAccess().clanExists(args[1], new Callback() + { + @Override + public void run(Boolean clanExists) + { + if (clanExists) + { + UtilPlayer.message(caller, F.main("Clans", "Clan name is already in use by another Clan.")); + } + else + { + Plugin.getClanDataAccess().createAndJoin(caller, args[1], new Callback() + { + @Override + public void run(ClanInfo data) + { + if (data == null) + { + // Hopefully shouldn't happen! + UtilPlayer.message(caller, F.main("Clans", "There was an error creating the clan. Please try again")); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "You created Clan " + C.cYellow + data.getName() + C.cGray + ".")); + } + } + }); + } + } + }); + } + + public void delete(final Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "disband", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + Plugin.getClanUtility().delete(caller); + } + + public void invite(Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "invite", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (Plugin.getTutorial().inTutorial(caller)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot invite others while in a tutorial.")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input an invitee.")); + return; + } + + Player target = UtilPlayer.searchOnline(caller, args[1], true); + if (target == null || _clansManager.getIncognitoManager().Get(target).Status) return; + + Plugin.getClanUtility().invite(caller, clan, target); + } + + public void stuck(final Player caller) + { +// if (_clansManager.getNetherManager().isInNether(caller)) +// { +// _clansManager.message(caller, "You are not allowed to free yourself in " + F.clansNether("The Nether") + "."); +// +// return; +// } + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "stuck"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + if (DelayedTask.Instance.HasTask(caller, "Spawn Teleport")) + { + _clansManager.message(caller, "You are already unsticking yourself."); + + return; + } + + ClanTerritory territory = Plugin.getClanUtility().getClaim(caller.getLocation()); + + String clanName = Plugin.getClanUtility().getClanByPlayer(caller) == null ? null : Plugin.getClanUtility().getClanByPlayer(caller).getName(); + + if (territory == null || territory.Safe || territory.Owner.equals(clanName)) + { + UtilPlayer.message(caller, F.main("Clans", "You must be in another Clan's territory to use this.")); + return; + } + + DelayedTask.Instance.doDelay(caller, "Wilderness Teleport", new Callback() { + public void run(DelayedTaskClient player) + { + // Do + + Location loc = getWildLoc(player.getPlayer().getLocation()); + + if (loc == null) + { + UtilPlayer.message(caller, F.main("Clans", "Error whilst finding location to teleport to.")); + return; + } + + player.getPlayer().teleport(loc); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You have been teleported to the Wilderness.")); + } + }, new Callback() { + public void run(DelayedTaskClient client) + { + UtilTextMiddle.display("", "Teleporting to Wilderness in " + F.time(UtilTime.MakeStr(Math.max(0, client.getTimeLeft("Wilderness Teleport")))), 0, 5, 0, client.getPlayer()); + } + }, new Callback() { + public void run(DelayedTaskClient client) + { + UtilPlayer.message(client.getPlayer(), F.main("Clans", "Teleport has been cancelled due to movement.")); + } + }, 2 * 60 * 1000, false); + + } + + public Location getWildLoc(Location origin) + { + Chunk wildLoc = origin.getChunk(); + + List worldChunks = Lists.newArrayList(origin.getWorld().getLoadedChunks()); + + Collections.sort( + worldChunks, + (c1, c2) -> + (int) ((int) + origin.distance( + UtilBlock.getHighest(origin.getWorld(), + c1.getBlock(7, origin.getBlockY(), 7).getLocation() + ).getLocation()) + - + origin.distance( + UtilBlock.getHighest(origin.getWorld(), + c2.getBlock(7, origin.getBlockY(), 7).getLocation() + ).getLocation()) + ) + ); + + for (Chunk chunk : worldChunks) + { + if (Plugin.getClanUtility().getClaim(chunk) == null) + { + return chunk.getBlock(6, UtilBlock.getHighest(origin.getWorld(), chunk.getBlock(6, 0, 6).getLocation()).getY(), 6).getLocation(); + } + } + + return null; + } + + public void join(final Player caller, String[] args) + { + ClansCommandExecutedEvent cevent = new ClansCommandExecutedEvent(caller, "join", args); + UtilServer.getServer().getPluginManager().callEvent(cevent); + + if (cevent.isCancelled()) + { + return; + } + + if (Plugin.getClanMemberUuidMap().containsKey(caller.getUniqueId())) + { + UtilPlayer.message(caller, F.main("Clans", "You are already in a Clan.")); + return; + } + + if (Plugin.leftRecently(caller.getUniqueId(), 20 * 60 * 1000) != null) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot join a Clan for " + C.mTime + UtilTime.MakeStr(Plugin.leftRecently(caller.getUniqueId(), 20 * 60 * 1000).getRight()) + C.mBody + ".")); + return; + } + + if (!Plugin.Get(caller).canJoin()) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot join a Clan for " + C.mTime + UtilTime.convertString(System.currentTimeMillis() - Plugin.Get(caller).getDelay(), 1, TimeUnit.FIT) + C.mBody + ".")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a Clan name.")); + return; + } + + if (!UtilInput.valid(args[1])) + { + UtilPlayer.message(caller, F.main("Clans", "Invalid characters in Clan name.")); + return; + } + + final ClanInfo clan = Plugin.getClanUtility().searchClanPlayer(caller, args[1], true); + if (clan == null) return; + + if (!clan.isInvited(caller.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You are not invited to " + F.elem("Clan " + clan.getName()) + ".")); + return; + } + + if (clan.getSize() >= clan.getMaxSize()) + { + UtilPlayer.message(caller, F.main("Clans", "The clan " + F.elem("Clan " + clan.getName()) + " is full and cannot be joined!")); + return; + } + + if (clan.getAllies() > clan.getAlliesMaxWithMemberCountOf(clan.getSize() + 1)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot join " + F.elem("Clan " + clan.getName()) + " until they remove some allies!")); + return; + } + + ClanJoinEvent event = new ClanJoinEvent(clan, caller); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) return; + + // Task + Plugin.getClanDataAccess().join(clan, caller, ClanRole.RECRUIT, new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + // Inform + UtilPlayer.message(caller, F.main("Clans", "You joined " + F.elem("Clan " + clan.getName()) + ".")); + clan.inform(F.name(caller.getName()) + " has joined your Clan.", caller.getName()); + } + else + { + UtilPlayer.message(caller, F.main("Clans", "There was an error processing your request")); + } + } + }); + + } + + public void leave(final Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "leave"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + final ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (clan.getMembers().get(caller.getUniqueId()).getRole() == ClanRole.LEADER && clan.getMembers().size() > 1) + { + UtilPlayer.message(caller, F.main("Clans", "You must pass on " + F.elem("Leadership") + " before leaving.")); + return; + } + + // Leave or Delete + if (clan.getMembers().size() > 1) + { + // Task + Plugin.getClanDataAccess().leave(clan, caller, new Callback() + { + @Override + public void run(Boolean data) + { + // Inform + UtilPlayer.message(caller, F.main("Clans", "You left " + F.elem("Clan " + clan.getName()) + ".")); + clan.inform(F.name(caller.getName()) + " has left your Clan.", null); + } + }); + } + else + { + delete(caller, args); + } + } + + public void kick(final Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "kick", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + final ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a Player to kick.")); + return; + } + + final String target = UtilPlayer.searchCollection(caller, args[1], clan.getMemberNameSet(), "Clan Member", true); + + _clansManager.getClanUtility().kick(caller, target); + } + + public void promote(Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "promote", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input player to promote.")); + return; + } + + final String targetName = UtilPlayer.searchCollection(caller, args[1], clan.getMemberNameSet(), "Clan Member", true); + + _clansManager.getClanUtility().promote(caller, targetName); + } + + public void demote(Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "demote", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input player to demote.")); + return; + } + + final String targetName = UtilPlayer.searchCollection(caller, args[1], clan.getMemberNameSet(), "Clan Member", true); + + _clansManager.getClanUtility().demote(caller, targetName); + } + + public void ally(Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "ally", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClanInfo cA = Plugin.getClanUtility().getClanByPlayer(caller); + + if (cA == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (cA.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && cA.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can manage Alliances.")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a Clan to ally.")); + return; + } + + ClanInfo cB = Plugin.getClanUtility().searchClanPlayer(caller, args[1], true); + + if (cB == null) return; + + if (cA.isSelf(cB.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot ally with yourself.")); + return; + } + + if (cA.isAlly(cB.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You are already allies with Clan" + F.elem(cB.getName())) + "."); + return; + } + + if (cA.getAllies() >= cA.getAlliesMax()) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot have any more allies.")); + return; + } + + if (cB.getAllies() >= cB.getAlliesMax()) + { + UtilPlayer.message(caller, F.main("Clans", "Clan " + F.elem(cB.getName()) + " cannot have any more allies.")); + return; + } + + if (!Recharge.Instance.usable(caller, "AllyReq" + cB.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "Please do not spam alliance requests.")); + return; + } + + if (cB.isRequested(cA.getName())) + { + // Task + Plugin.getClanDataAccess().ally(cA, cB, caller.getName()); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You accepted alliance with Clan " + F.elem(cB.getName()) + ".")); + cA.inform(F.name(caller.getName()) + " accepted alliance with Clan " + F.elem(cB.getName()) + ".", caller.getName()); + cB.inform("Clan " + F.elem(cA.getName()) + " has accepted alliance with you.", null); + } + else + { + // Task + Plugin.getClanDataAccess().requestAlly(cA, cB, caller.getName()); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You requested alliance with Clan " + F.elem(cB.getName()) + ".")); + cA.inform(F.name(caller.getName()) + " has requested alliance with Clan " + F.elem(cB.getName()) + ".", caller.getName()); + cB.inform("Clan " + F.elem(cA.getName()) + " has requested alliance with you.", null); + + Recharge.Instance.use(caller, "AllyReq" + cB.getName(), java.util.concurrent.TimeUnit.MINUTES.toMillis(1), false, false); + } + } + +// public void trust(Player caller, String[] args) +// { +// ClanInfo cA = Plugin.getClan(Plugin.getClanMemberUuidMap().get(caller.getUniqueId()).getName()); +// +// if (cA == null) +// { +// _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", "You are not in a Clan.")); +// return; +// } +// +// if (cA.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && cA.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) +// { +// _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", "Only the Clan Leader and Admins can manage Trust.")); +// return; +// } +// +// if (args.length < 2) +// { +// _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", "You did not input a Clan to enemy.")); +// return; +// } +// +// ClanInfo cB = Plugin.getClanUtility().searchClanPlayer(caller, args[1], true); +// +// if (cB == null) return; +// +// if (!cA.isAlly(cB.getName())) +// { +// _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", "You must be allied to trust a clan!")); +// return; +// } +// +// // Task +// if (Plugin.getClanDataAccess().trust(cA, cB, caller.getName())) +// { +// // Inform +// _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", "You gave trust to " + F.elem("Clan " + cB.getName()) + ".")); +// cA.inform(F.name(caller.getName()) + " has given trust to " + F.elem("Clan " + cB.getName()) + ".", caller.getName()); +// cB.inform(F.elem("Clan " + cA.getName()) + " has given trust to you.", null); +// } +// else +// { +// // Inform +// _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", "You revoked trust to " + F.elem("Clan " + cB.getName()) + ".")); +// cA.inform(F.name(caller.getName()) + " has revoked trust to " + F.elem("Clan " + cB.getName()) + ".", caller.getName()); +// cB.inform(F.elem("Clan " + cA.getName()) + " has revoked trust to you.", null); +// } +// } + + public void neutral(Player caller, String[] args) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "neutral", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClanInfo cA = Plugin.getClanMemberUuidMap().get(caller.getUniqueId()); + + if (cA == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + + if (cA.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && cA.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can manage relationships.")); + return; + } + + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a Clan to set neutrality with.")); + return; + } + + ClanInfo cB = Plugin.getClanUtility().searchClanPlayer(caller, args[1], true); + + if (cB == null) return; + + if (cB.isSelf(cA.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You prefer to think of yourself positively...")); + } + else if (cB.isNeutral(cA.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You are already neutral with " + F.elem("Clan " + cB.getName()) + ".")); + } + else if (cB.isAlly(cA.getName())) + { + // Task + Plugin.getClanDataAccess().neutral(cA, cB, caller.getName(), true); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You revoked alliance with " + F.elem("Clan " + cB.getName()) + ".")); + cA.inform(F.name(caller.getName()) + " revoked alliance with " + F.elem("Clan " + cB.getName()) + ".", caller.getName()); + cB.inform(F.elem("Clan " + cA.getName()) + " has revoked alliance with you.", null); + } + } + + public void claim(Player caller, String args[]) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "claim", args); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + +// if (_clansManager.getNetherManager().isInNether(caller)) +// { +// _clansManager.message(caller, "You are not allowed to claim territory in " + F.clansNether("The Nether") + "."); +// +// return; +// } + + Plugin.getClanUtility().claim(caller); + } + + public void unclaim(Player caller, String[] args) + { +// if (_clansManager.getNetherManager().isInNether(caller)) +// { +// _clansManager.message(caller, "You are not allowed to unclaim territory in " + F.clansNether("The Nether") + "."); +// +// return; +// } + + if (args.length > 1) + { + if (args[1].equalsIgnoreCase("all") || args[1].equalsIgnoreCase("a")) + { + unclaimall(caller); + return; + } + } + + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "unclaim"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + Plugin.getClanUtility().unclaim(caller, caller.getLocation().getChunk()); + } + + public boolean unclaimSteal(Player caller, ClanInfo clientClan, ClanInfo ownerClan) + { + if (!_clansManager.canUnclaimChunk(clientClan, ownerClan)) + { + return false; + } + + // Change Inform + UtilPlayer.message(caller, F.main("Clans", "You can no longer 'steal' territory. " + "You simply unclaim it and it can not be reclaimed by anyone for 30 mintes." + "This was done to improve gameplay. Enjoy!")); + + // Inform + UtilServer.broadcast(F.main("Clans", F.elem(clientClan.getName()) + " unclaimed from " + F.elem(ownerClan.getName()) + " at " + F.elem(UtilWorld.locToStrClean(caller.getLocation())) + ".")); + + // Unclaim + Plugin.getClanDataAccess().unclaim(ClaimLocation.of(caller.getLocation().getChunk()), caller.getName(), true); + + return true; + } + + public void unclaimall(Player caller) + { + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "unclaimall"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + Plugin.getClanUtility().unclaimAll(caller); + } + +// public void map(Player caller, String[] args) +// { +// ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "map"); +// UtilServer.getServer().getPluginManager().callEvent(event); +// +// if (event.isCancelled()) +// { +// return; +// } +// +// Plugin.getItemMapManager().setMap(caller); +// } + + public void home(final Player caller, String[] args) + { + if (args.length > 1) + { + if (args[1].equalsIgnoreCase("set") || args[1].equalsIgnoreCase("s")) + { + homeSet(caller); + return; + } + } + + final ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + if (clan == null) + { + //teleport to spawn point + Spawn.getInstance().getSpawnLocation(); UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + + return; + } + + if (clan.getHome() == null) + { + UtilPlayer.message(caller, F.main("Clans", "Your Clan has not set a Home")); + return; + } + + if (!clan.getClaimSet().contains(ClaimLocation.of(clan.getHome().getChunk()))) + { + UtilPlayer.message(caller, F.main("Clans", "Your Clan has lost its Home Territory.")); + return; + } + + Location home = clan.getHome(); + + if (!(home.getBlock().getType().equals(Material.BED_BLOCK) && home.add(0, 1, 0).getBlock().getType().equals(Material.AIR)) && home.add(0, 2, 0).getBlock().getType().equals(Material.AIR)) + { + UtilPlayer.message(caller, F.main("Clans", "Your Clan's bed has been destroyed, or is obstructed.")); + return; + } + + /* + * CoreClient client = _plugin.getClientManager().Get(caller); for + * (Player cur : clan.GetHome().getWorld().getPlayers()) if + * (client.Clan().GetRelation(cur.getName()) == ClanRelation.NEUTRAL) if + * (clan.GetClaimSet().contains(UtilWorld.chunkToStr(cur.getLocation(). + * getChunk()))) { _manager.getTutorials().sendTutorialMsg(caller, F.main("Clans", + * "You cannot use Clan Home with enemies in your Territory.")); return; + * } + */ + + if (!Recharge.Instance.usable(caller, "Home Teleport", true)) + { + return; + } + + if (!UtilTime.elapsed(_clansManager.getCombatManager().getLog(caller).GetLastCombatEngaged(), 15000)) + { + long remain = _clansManager.getCombatManager().getLog(caller).GetLastCombatEngaged() + 15000 - System.currentTimeMillis(); + UtilPlayer.message(caller, F.main("Clans", "You are combat tagged for " + F.elem(UtilTime.MakeStr(remain)) + "!")); + return; + } + + // Event + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "tphome"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + DelayedTask.Instance.doDelay(caller, "Home Teleport", new Callback() { + public void run(DelayedTaskClient player) + { + Recharge.Instance.use(caller, "Home Teleport", 30 * 60 * 1000, true, false); + + // Do + Plugin.getTeleport().TP(caller, clan.getHome().add(0, 1, 0)); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You teleported to your Clan Home " + UtilWorld.locToStrClean(caller.getLocation()) + ".")); + } + }, new Callback() { + public void run(DelayedTaskClient client) + { + UtilTextMiddle.display("", "Teleporting to Clan Home in " + F.time(UtilTime.MakeStr(Math.max(0, client.getTimeLeft("Home Teleport")))), 0, 5, 0, client.getPlayer()); + } + }, new Callback() { + public void run(DelayedTaskClient client) + { + UtilPlayer.message(client.getPlayer(), F.main("Clans", "Teleport has been cancelled due to movement.")); + } + }, 15 * 1000, false); + } + + public void homeSet(Player caller) + { + ClanInfo clan = Plugin.getClanUtility().getClanByPlayer(caller); + + // Event + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "homeset"); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + if (clan == null) + { + UtilPlayer.message(caller, F.main("Clans", "You are not in a Clan.")); + return; + } + +// if (_clansManager.getNetherManager().isInNether(caller)) +// { +// _clansManager.message(caller, "You are not allowed to set your Clan Home in " + F.clansNether("The Nether") + "."); +// +// return; +// } + + if (clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.LEADER && clan.getMembers().get(caller.getUniqueId()).getRole() != ClanRole.ADMIN) + { + UtilPlayer.message(caller, F.main("Clans", "Only the Clan Leader and Admins can manage Clan Home.")); + return; + } + + if (Plugin.getClanUtility().getOwner(caller.getLocation()) == null) + { + UtilPlayer.message(caller, F.main("Clans", "You must set your Clan Home in your own Territory.")); + return; + } + + if (!Plugin.getClanUtility().getOwner(caller.getLocation()).isSelf(clan.getName())) + { + UtilPlayer.message(caller, F.main("Clans", "You must set your Clan Home in your own Territory.")); + return; + } + + if (!(caller.getLocation().add(0, 1, 0).getBlock().getType().equals(Material.AIR) && caller.getLocation().add(0, 2, 0).getBlock().getType().equals(Material.AIR))) + { + UtilPlayer.message(caller, F.main("Clans", "This is not a suitable place for a bed.")); + return; + } + + // Place New + boolean bedPlaced = UtilBlock.placeBed(caller.getLocation(), BlockFace.valueOf(EnumDirection.fromAngle(caller.getLocation().getYaw()).name()), false, false); + + if (!bedPlaced) + { + UtilPlayer.message(caller, F.main("Clans", "This is not a suitable place for a bed.")); + return; + } + + // Cleanup old + if (clan.getHome() != null) + { + System.out.println("<-old bed cleanup-> <--> " + UtilBlock.deleteBed(clan.getHome())); + } + + // Task + Plugin.getClanDataAccess().setHome(clan, caller.getLocation(), caller.getName()); + + Plugin.ClanTips.displayTip(TipType.SETHOME, caller); + + // Inform + UtilPlayer.message(caller, F.main("Clans", "You set Clan Home to " + F.elem(UtilWorld.locToStrClean(caller.getLocation())) + ".")); + clan.inform(caller.getName() + " set Clan Home to " + F.elem(UtilWorld.locToStrClean(caller.getLocation())) + ".", caller.getName()); + } + + public void infoClan(Player caller, String search) + { +// System.out.println(search); + + if (search == null) + { + UtilPlayer.message(caller, F.main("Clans", "You did not input a search parameter.")); + return; + } + + ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "info", search); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + ClanInfo clan = Plugin.getClanUtility().searchClanPlayer(caller, search, true); + if (clan == null) return; + + _clansManager.getClanShop().openClanWho(caller, clan); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/KillCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/KillCommand.java new file mode 100644 index 00000000..2e9012bc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/KillCommand.java @@ -0,0 +1,48 @@ +package mineplex.game.clans.clans.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.spawn.Spawn; + +public class KillCommand extends CommandBase +{ + public KillCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.SUICIDE_COMMAND, "suicide", "kill"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (!UtilTime.elapsed(Plugin.getCombatManager().getLog(caller).GetLastCombatEngaged(), Spawn.COMBAT_TAG_DURATION)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot use this command whilst in combat.")); + return; + } + if (Plugin.getTutorial().inTutorial(caller)) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot use this command whilst in the tutorial.")); + return; + } + if (Plugin.getClanUtility().isSafe(caller.getLocation()) || (Plugin.getClanUtility().getClaim(caller.getLocation()) != null && Plugin.getClanUtility().getClaim(caller.getLocation()).Owner.equalsIgnoreCase("Spawn"))) + { + UtilPlayer.message(caller, F.main("Clans", "You cannot use this command whilst in a safezone!")); + return; + } + if (Recharge.Instance.use(caller, "Suicide", 5000, false, false)) + { + UtilPlayer.message(caller, F.main("Clans", "Run the command again to confirm.")); + return; + } + + UtilPlayer.message(caller, F.main("Clans", "You have imploded.")); + + caller.setHealth(0D); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java new file mode 100644 index 00000000..b5f55630 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java @@ -0,0 +1,20 @@ +package mineplex.game.clans.clans.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.clans.ClansManager; + +public class MapCommand extends CommandBase +{ + public MapCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.MAP_COMMAND, "map", "clansmap"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.getItemMapManager().setMap(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/RegionsCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/RegionsCommand.java new file mode 100644 index 00000000..4b3bc2a4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/RegionsCommand.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.clans.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; + +public class RegionsCommand extends CommandBase +{ + private ClansManager _manager; + + public RegionsCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.REGION_CLEAR_COMMAND, "region-reset"); + + _manager = plugin; + } + + @Override + public void Execute(Player caller, String[] args) + { + UtilPlayer.message(caller, F.main("Regions", "Resetting clans regions!")); + _manager.getClanRegions().resetRegions(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/SpeedCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/SpeedCommand.java new file mode 100644 index 00000000..4962db00 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/SpeedCommand.java @@ -0,0 +1,105 @@ +package mineplex.game.clans.clans.commands; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; + +public class SpeedCommand extends CommandBase +{ + public SpeedCommand(ClansManager plugin) + { + super(plugin, ClansManager.Perm.SPEED_COMMAND, "speed"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 3) + { + UtilPlayer.message(caller, F.help("/speed ", "Set a player's walk/fly speed to an amount", ChatColor.GOLD)); + return; + } + Player player = Bukkit.getPlayer(args[0]); + if (player == null) + { + UtilPlayer.message(caller, F.main("Speed", "That player is not online!")); + return; + } + if (args[1].equalsIgnoreCase("walk")) + { + float amount; + try + { + amount = Float.parseFloat(args[2]); + } + catch (NumberFormatException ex) + { + UtilPlayer.message(caller, F.main("Speed", "That is not a number!")); + return; + } + String error = validateSpeed(amount); + if (error == null) + { + player.setWalkSpeed(amount); + UtilPlayer.message(caller, F.main("Speed", "Set " + player.getName() + "'s walk speed to " + amount)); + return; + } + else + { + UtilPlayer.message(caller, F.main("Speed", error)); + return; + } + } + else if (args[1].equalsIgnoreCase("fly")) + { + float amount; + try + { + amount = Float.parseFloat(args[2]); + } + catch (NumberFormatException ex) + { + UtilPlayer.message(caller, F.main("Speed", "That is not a number!")); + return; + } + String error = validateSpeed(amount); + if (error == null) + { + player.setFlySpeed(amount); + UtilPlayer.message(caller, F.main("Speed", "Set " + player.getName() + "'s fly speed to " + amount)); + return; + } + else + { + UtilPlayer.message(caller, F.main("Speed", error)); + return; + } + } + else + { + UtilPlayer.message(caller, F.main("Speed","That is not a valid speed type!")); + return; + } + } + + private String validateSpeed(float value) + { + if (value < 0.0F) + { + if (value < -1.0F) + { + return value + " is too low"; + } + } + else if(value > 1.0F) + { + return value + " is too high"; + } + return null; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/data/PlayerClan.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/data/PlayerClan.java new file mode 100644 index 00000000..f1e20420 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/data/PlayerClan.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.clans.data; + +import org.bukkit.entity.Player; + +import mineplex.game.clans.clans.ClanInfo; + +public class PlayerClan +{ + private Player _player; + private ClanInfo _clan; + + public PlayerClan(Player player, ClanInfo clan) + { + _player = player; + _clan = clan; + } + + public Player getPlayer() + { + return _player; + } + + public ClanInfo getClan() + { + return _clan; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanCreatedEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanCreatedEvent.java new file mode 100644 index 00000000..8490a08d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanCreatedEvent.java @@ -0,0 +1,206 @@ +package mineplex.game.clans.clans.event; + +import java.sql.Timestamp; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.core.repository.tokens.ClanToken; + +public class ClanCreatedEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _founder; + private int _id; + private String _name; + private String _description; + private String _home; + private boolean _admin; + private int _energy; + private int _kills; + private int _murders; + private int _deaths; + private int _warWins; + private int _warLosses; + private Timestamp _dateCreated; + private Timestamp _lastOnline; + + private boolean _cancelled; + + public ClanCreatedEvent(ClanToken token, Player founder) + { + _founder = founder; + + _id = token.Id; + _name = token.Name; + _description = token.Description; + _home = token.Home; + _admin = token.Admin; + _energy = token.Energy; + _kills = token.Kills; + _murders = token.Murder; + _deaths = token.Deaths; + _warWins = token.WarWins; + _warLosses = token.WarLosses; + _dateCreated = token.DateCreated; + _lastOnline = token.LastOnline; + } + + public Player getFounder() + { + return _founder; + } + + public int getId() + { + return _id; + } + + public void setId(int id) + { + _id = id; + } + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _name = name; + } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + _description = description; + } + + public String getHome() + { + return _home; + } + + public void setHome(String home) + { + _home = home; + } + + public boolean isAdmin() + { + return _admin; + } + + public void setAdmin(boolean admin) + { + _admin = admin; + } + + public int getEnergy() + { + return _energy; + } + + public void setEnergy(int energy) + { + _energy = energy; + } + + public int getKills() + { + return _kills; + } + + public void setKills(int kills) + { + _kills = kills; + } + + public int getMurders() + { + return _murders; + } + + public void setMurders(int murders) + { + _murders = murders; + } + + public int getDeaths() + { + return _deaths; + } + + public void setDeaths(int deaths) + { + _deaths = deaths; + } + + public int getWarWins() + { + return _warWins; + } + + public void setWarWins(int warWins) + { + _warWins = warWins; + } + + public int getWarLosses() + { + return _warLosses; + } + + public void setWarLosses(int warLosses) + { + _warLosses = warLosses; + } + + public Timestamp getDateCreated() + { + return _dateCreated; + } + + public void setDateCreated(Timestamp dateCreated) + { + _dateCreated = dateCreated; + } + + public Timestamp getLastOnline() + { + return _lastOnline; + } + + public void setLastOnline(Timestamp lastOnline) + { + _lastOnline = lastOnline; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanCreationCompleteEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanCreationCompleteEvent.java new file mode 100644 index 00000000..789e55d2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanCreationCompleteEvent.java @@ -0,0 +1,194 @@ +package mineplex.game.clans.clans.event; + +import java.sql.Timestamp; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.core.repository.tokens.ClanToken; + +public class ClanCreationCompleteEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _founder; + private int _id; + private String _name; + private String _description; + private String _home; + private boolean _admin; + private int _energy; + private int _kills; + private int _murders; + private int _deaths; + private int _warWins; + private int _warLosses; + private Timestamp _dateCreated; + private Timestamp _lastOnline; + + public ClanCreationCompleteEvent(ClanToken token, Player founder) + { + _founder = founder; + + _id = token.Id; + _name = token.Name; + _description = token.Description; + _home = token.Home; + _admin = token.Admin; + _energy = token.Energy; + _kills = token.Kills; + _murders = token.Murder; + _deaths = token.Deaths; + _warWins = token.WarWins; + _warLosses = token.WarLosses; + _dateCreated = token.DateCreated; + _lastOnline = token.LastOnline; + } + + public Player getFounder() + { + return _founder; + } + + public int getId() + { + return _id; + } + + public void setId(int id) + { + _id = id; + } + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _name = name; + } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + _description = description; + } + + public String getHome() + { + return _home; + } + + public void setHome(String home) + { + _home = home; + } + + public boolean isAdmin() + { + return _admin; + } + + public void setAdmin(boolean admin) + { + _admin = admin; + } + + public int getEnergy() + { + return _energy; + } + + public void setEnergy(int energy) + { + _energy = energy; + } + + public int getKills() + { + return _kills; + } + + public void setKills(int kills) + { + _kills = kills; + } + + public int getMurders() + { + return _murders; + } + + public void setMurders(int murders) + { + _murders = murders; + } + + public int getDeaths() + { + return _deaths; + } + + public void setDeaths(int deaths) + { + _deaths = deaths; + } + + public int getWarWins() + { + return _warWins; + } + + public void setWarWins(int warWins) + { + _warWins = warWins; + } + + public int getWarLosses() + { + return _warLosses; + } + + public void setWarLosses(int warLosses) + { + _warLosses = warLosses; + } + + public Timestamp getDateCreated() + { + return _dateCreated; + } + + public void setDateCreated(Timestamp dateCreated) + { + _dateCreated = dateCreated; + } + + public Timestamp getLastOnline() + { + return _lastOnline; + } + + public void setLastOnline(Timestamp lastOnline) + { + _lastOnline = lastOnline; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanDeleteEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanDeleteEvent.java new file mode 100644 index 00000000..6076a1ca --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanDeleteEvent.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class ClanDeleteEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private ClanInfo _clanInfo; + + public ClanDeleteEvent(ClanInfo clanInfo) + { + _clanInfo = clanInfo; + } + + public ClanInfo getClanInfo() + { + return _clanInfo; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanDisbandedEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanDisbandedEvent.java new file mode 100644 index 00000000..d2d1e444 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanDisbandedEvent.java @@ -0,0 +1,54 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class ClanDisbandedEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _disbander; + private ClanInfo _clan; + + private boolean _cancelled; + + public ClanDisbandedEvent(ClanInfo info, Player disbander) + { + _disbander = disbander; + _clan = info; + } + + public Player getDisbander() + { + return _disbander; + } + + public ClanInfo getClan() + { + return _clan; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanJoinEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanJoinEvent.java new file mode 100644 index 00000000..f538dae9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanJoinEvent.java @@ -0,0 +1,56 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class ClanJoinEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + + private ClanInfo _clan; + + private boolean _cancelled; + + public ClanJoinEvent(ClanInfo clan, Player player) + { + _player = player; + + _clan = clan; + } + + public Player getPlayer() + { + return _player; + } + + public ClanInfo getClan() + { + return _clan; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanLeaveEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanLeaveEvent.java new file mode 100644 index 00000000..3c5f6156 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanLeaveEvent.java @@ -0,0 +1,56 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansPlayer; + +public class ClanLeaveEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private ClansPlayer _player; + + private ClanInfo _clan; + + private boolean _cancelled; + + public ClanLeaveEvent(ClanInfo clan, ClansPlayer clansPlayer) + { + _player = clansPlayer; + + _clan = clan; + } + + public ClansPlayer getPlayer() + { + return _player; + } + + public ClanInfo getClan() + { + return _clan; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanSetHomeEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanSetHomeEvent.java new file mode 100644 index 00000000..bd2f3db1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanSetHomeEvent.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class ClanSetHomeEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private ClanInfo _clan; + + private Location _loc; + + private boolean _cancelled; + + public ClanSetHomeEvent(ClanInfo clan, Player player, Location location) + { + _player = player; + _loc = location; + _clan = clan; + } + + public Player getPlayer() + { + return _player; + } + + public Location getLocation() + { + return _loc; + } + + public ClanInfo getClan() + { + return _clan; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanTipEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanTipEvent.java new file mode 100644 index 00000000..38c34851 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClanTipEvent.java @@ -0,0 +1,55 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanTips.TipType; + +public class ClanTipEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private TipType _tip; + + private boolean _cancelled; + + public ClanTipEvent(TipType tip, Player player) + { + _player = player; + + _tip = tip; + } + + public Player getPlayer() + { + return _player; + } + + public TipType getTip() + { + return _tip; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansCommandExecutedEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansCommandExecutedEvent.java new file mode 100644 index 00000000..277df4f9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansCommandExecutedEvent.java @@ -0,0 +1,76 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ClansCommandExecutedEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private String _command; + private String[] _args; + + private boolean _cancelled; + + public ClansCommandExecutedEvent(Player player, String command, String... args) + { + _player = player; + _command = command; + _args = args; + } + + public ClansCommandExecutedEvent(Player player, String command, Object... args) + { + _player = player; + _command = command; + + String[] strArgs = new String[args != null ? args.length : 0]; + + int index = 0; + for (Object obj : args) + { + strArgs[index] = obj.toString(); + + index++; + } + + _args = strArgs; + } + + public Player getPlayer() + { + return _player; + } + + public String getCommand() + { + return _command; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public String[] getArguments() + { + return _args; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansCommandPreExecutedEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansCommandPreExecutedEvent.java new file mode 100644 index 00000000..5c8695c3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansCommandPreExecutedEvent.java @@ -0,0 +1,68 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ClansCommandPreExecutedEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private String[] _args; + + private boolean _cancelled; + + public ClansCommandPreExecutedEvent(Player player, String... args) + { + _player = player; + _args = args; + } + + public ClansCommandPreExecutedEvent(Player player, Object... args) + { + _player = player; + + String[] strArgs = new String[args != null ? args.length : 0]; + + int index = 0; + for (Object obj : args) + { + strArgs[index] = obj.toString(); + + index++; + } + + _args = strArgs; + } + + public Player getPlayer() + { + return _player; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public String[] getArguments() + { + return _args; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerBuyItemEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerBuyItemEvent.java new file mode 100644 index 00000000..ac35eecf --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerBuyItemEvent.java @@ -0,0 +1,99 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.shop.ShopItemButton; + +public class ClansPlayerBuyItemEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private ShopPageBase _page; + private int _cost; + private int _amount; + private ItemStack _item; + + private ShopItemButton> _button; + + private boolean _cancelled; + + public ClansPlayerBuyItemEvent(Player player, ShopPageBase page, ShopItemButton> shopItemButton, ItemStack item, int cost, int amount) + { + _page = page; + _button = shopItemButton; + _amount = amount; + _item = item; + _player = player; + _cost = cost; + } + + public Player getPlayer() + { + return _player; + } + + public ShopPageBase getPage() + { + return _page; + } + + public ItemStack getItem() + { + return _item; + } + + public void setItem(ItemStack item) + { + _item = item; + } + + public int getCost() + { + return _cost; + } + + public void setCost(int cost) + { + _cost = cost; + } + + public int getAmount() + { + return _amount; + } + + public void setAmount(int amount) + { + _amount = amount; + } + + public ShopItemButton> getButton() + { + return _button; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerDeathEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerDeathEvent.java new file mode 100644 index 00000000..a59064ac --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerDeathEvent.java @@ -0,0 +1,51 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.PlayerDeathEvent; + +import mineplex.game.clans.clans.data.PlayerClan; + +public class ClansPlayerDeathEvent extends Event +{ + private PlayerDeathEvent _event; + private PlayerClan _player; + private PlayerClan _killer; + + public ClansPlayerDeathEvent(PlayerDeathEvent event, PlayerClan player, PlayerClan killer) + { + _event = event; + _player = player; + _killer = killer; + } + + public PlayerDeathEvent getEvent() + { + return _event; + } + + public PlayerClan getPlayer() + { + return _player; + } + + public PlayerClan getKiller() + { + return _killer; + } + + public void setPlayer(PlayerClan player) + { + _player = player; + } + + public void setKiller(PlayerClan killer) + { + _killer = killer; + } + + // Bukkit event stuff + private static final HandlerList handlers = new HandlerList(); + public static HandlerList getHandlerList() { return handlers; } + public HandlerList getHandlers() { return handlers; } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerSellItemEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerSellItemEvent.java new file mode 100644 index 00000000..f957356f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansPlayerSellItemEvent.java @@ -0,0 +1,99 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.shop.ShopItemButton; + +public class ClansPlayerSellItemEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private ShopPageBase _page; + private int _cost; + private int _amount; + private ItemStack _item; + + private ShopItemButton> _button; + + private boolean _cancelled; + + public ClansPlayerSellItemEvent(Player player, ShopPageBase page, ShopItemButton> shopItemButton, ItemStack item, int cost, int amount) + { + _page = page; + _button = shopItemButton; + _amount = amount; + _item = item; + _player = player; + _cost = cost; + } + + public Player getPlayer() + { + return _player; + } + + public ShopPageBase getPage() + { + return _page; + } + + public ItemStack getItem() + { + return _item; + } + + public void setItem(ItemStack item) + { + _item = item; + } + + public int getCost() + { + return _cost; + } + + public void setCost(int cost) + { + _cost = cost; + } + + public int getAmount() + { + return _amount; + } + + public void setAmount(int amount) + { + _amount = amount; + } + + public ShopItemButton> getButton() + { + return _button; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansShopAddButtonEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansShopAddButtonEvent.java new file mode 100644 index 00000000..535fb68b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansShopAddButtonEvent.java @@ -0,0 +1,138 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.core.shop.ShopBase; + +public class ClansShopAddButtonEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private final Player _player; + private final ShopBase _shop; + private Material _material; + private int _buyPrice; + private int _sellPrice; + private byte _data; + private String _displayName; + private int _amount; + private int _slot; + + private boolean _cancelled; + + public ClansShopAddButtonEvent(Player player, ShopBase shop, int slot, Material material, int buyPrice, int sellPrice, byte data, String displayName, int amount) + { + _player = player; + _shop = shop; + _slot = slot; + _material = material; + _buyPrice = buyPrice; + _sellPrice = sellPrice; + _data = data; + _displayName = displayName; + _amount = amount; + } + + public Player getPlayer() + { + return _player; + } + + public ShopBase getShop() + { + return _shop; + } + + public Material getMaterial() + { + return _material; + } + + public int getBuyPrice() + { + return _buyPrice; + } + + public void setBuyPrice(int buyPrice) + { + _buyPrice = buyPrice; + } + + public int getSellPrice() + { + return _sellPrice; + } + + public void setSellPrice(int sellPrice) + { + _sellPrice = sellPrice; + } + + public int getSlot() + { + return _slot; + } + + public void setSlot(int slot) + { + _slot = slot; + } + + public byte getData() + { + return _data; + } + + public void setData(byte data) + { + _data = data; + } + + public void setMaterial(Material material) + { + _material = material; + } + + public void setDisplayName(String displayName) + { + _displayName = displayName; + } + + public void setAmount(int amount) + { + _amount = amount; + } + + public String getDisplayName() + { + return _displayName; + } + + public int getAmount() + { + return _amount; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansWaterPlaceEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansWaterPlaceEvent.java new file mode 100644 index 00000000..c6826eee --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/ClansWaterPlaceEvent.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ClansWaterPlaceEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private Block _block; + + private boolean _cancelled; + + public ClansWaterPlaceEvent(Player player, Block block) + { + _player = player; + _block = block; + } + + public Player getPlayer() + { + return _player; + } + + public Block getBlock() + { + return _block; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/EnergyPageBuildEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/EnergyPageBuildEvent.java new file mode 100644 index 00000000..4212010b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/EnergyPageBuildEvent.java @@ -0,0 +1,58 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.core.shop.ShopBase; + +public class EnergyPageBuildEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private boolean _free; + private boolean _cancelled; + + private Player _player; + + public EnergyPageBuildEvent(Player player) + { + _player = player; + } + + public Player getPlayer() + { + return _player; + } + + public boolean free() + { + return _free; + } + + public void setFree(boolean free) + { + _free = free; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/IronDoorOpenEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/IronDoorOpenEvent.java new file mode 100644 index 00000000..5c22c522 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/IronDoorOpenEvent.java @@ -0,0 +1,58 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called before an iron door is opened by right clicking. + * + * (Custom mechanic in Clans) + */ +public class IronDoorOpenEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private Block _block; + + private boolean _cancelled; + + public IronDoorOpenEvent(Player player, Block block) + { + _player = player; + _block = block; + } + + public Player getPlayer() + { + return _player; + } + + public Block getBlock() + { + return _block; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerClaimTerritoryEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerClaimTerritoryEvent.java new file mode 100644 index 00000000..35fc5eaf --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerClaimTerritoryEvent.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.Chunk; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class PlayerClaimTerritoryEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _claimer; + private Chunk _claimedChunk; + + private boolean _cancelled; + + private ClanInfo _clan; + + public PlayerClaimTerritoryEvent(Player claimer, Chunk claimedChunk, ClanInfo clan) + { + _claimer = claimer; + _claimedChunk = claimedChunk; + _clan = clan; + } + + public Player getClaimer() + { + return _claimer; + } + + public ClanInfo getClan() + { + return _clan; + } + + public Chunk getClaimedChunk() + { + return _claimedChunk; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerEnterTerritoryEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerEnterTerritoryEvent.java new file mode 100644 index 00000000..ef243563 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerEnterTerritoryEvent.java @@ -0,0 +1,67 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class PlayerEnterTerritoryEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private String _newTerritory; + private String _lastTerritory; + private Player _player; + + private boolean _sendMessage; + + private boolean _safe; + + public PlayerEnterTerritoryEvent(Player player, String lastTerritory, String newTerritory, boolean safe, boolean sendMessage) + { + _player = player; + _lastTerritory = lastTerritory; + _newTerritory = newTerritory; + _safe = safe; + _sendMessage = sendMessage; + } + + public Player getPlayer() + { + return _player; + } + + public boolean willSendMessage() + { + return _sendMessage; + } + + public void setSendMessage(boolean flag) + { + _sendMessage = flag; + } + + public String getLastTerritory() + { + return _lastTerritory; + } + + public String getNewTerritory() + { + return _newTerritory; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public boolean isSafe() + { + return _safe; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerPreClaimTerritoryEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerPreClaimTerritoryEvent.java new file mode 100644 index 00000000..e74cd8d9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerPreClaimTerritoryEvent.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.Chunk; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class PlayerPreClaimTerritoryEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _claimer; + private Chunk _claimedChunk; + + private boolean _cancelled; + + private ClanInfo _clan; + + public PlayerPreClaimTerritoryEvent(Player claimer, Chunk claimedChunk, ClanInfo clan) + { + _claimer = claimer; + _claimedChunk = claimedChunk; + _clan = clan; + } + + public Player getClaimer() + { + return _claimer; + } + + public ClanInfo getClan() + { + return _clan; + } + + public Chunk getClaimedChunk() + { + return _claimedChunk; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerUnClaimTerritoryEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerUnClaimTerritoryEvent.java new file mode 100644 index 00000000..8d83363d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PlayerUnClaimTerritoryEvent.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.Chunk; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.ClanInfo; + +public class PlayerUnClaimTerritoryEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _unClaimer; + private Chunk _unClaimedChunk; + private ClanInfo _clan; + + private boolean _cancelled; + + public PlayerUnClaimTerritoryEvent(Player unClaimer, Chunk unClaimedChunk, ClanInfo clan) + { + _unClaimer = unClaimer; + _unClaimedChunk = unClaimedChunk; + _clan = clan; + } + + public Player getUnClaimer() + { + return _unClaimer; + } + + public Chunk getUnClaimedChunk() + { + return _unClaimedChunk; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public ClanInfo getClan() + { + return _clan; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PreEnergyShopBuyEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PreEnergyShopBuyEvent.java new file mode 100644 index 00000000..6c0af391 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/event/PreEnergyShopBuyEvent.java @@ -0,0 +1,58 @@ +package mineplex.game.clans.clans.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class PreEnergyShopBuyEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private boolean _cancelled; + + private Player _player; + private int _energy; + private int _cost; + + public PreEnergyShopBuyEvent(Player player, int energy, int cost) + { + _player = player; + _energy = energy; + _cost = cost; + } + + public Player getPlayer() + { + return _player; + } + + public int getCost() + { + return _cost; + } + + public int getEnergy() + { + return _energy; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/ClansFreezeManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/ClansFreezeManager.java new file mode 100644 index 00000000..ce6ba211 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/ClansFreezeManager.java @@ -0,0 +1,428 @@ +package mineplex.game.clans.clans.freeze; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.google.common.collect.Sets; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.recharge.Recharge; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.clans.event.IronDoorOpenEvent; +import mineplex.game.clans.clans.freeze.commands.FreezeCommand; +import mineplex.game.clans.clans.freeze.commands.PanicCommand; +import mineplex.game.clans.clans.freeze.commands.UnfreezeCommand; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class ClansFreezeManager extends MiniPlugin +{ + public enum Perm implements Permission + { + FREEZE_COMMAND, + UNFREEZE_COMMAND, + PANIC_COMMAND, + NOTIFY, + } + + private static final long FREEZE_MESSAGE_INTERVAL = 10000; + private static final Set CONTAINERS = Sets.newHashSet(Material.CHEST, Material.TRAPPED_CHEST, Material.HOPPER, Material.FURNACE, Material.BURNING_FURNACE, Material.DISPENSER, Material.DROPPER, Material.WORKBENCH, Material.BREWING_STAND); + + private final CoreClientManager _clientManager; + private final Map _frozen = new HashMap<>(); + private final Map _panic = new HashMap<>(); + + public ClansFreezeManager(JavaPlugin plugin, CoreClientManager clientManager) + { + super("Freeze", plugin); + + _clientManager = clientManager; + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.CMOD.setPermission(Perm.FREEZE_COMMAND, false, true); + PermissionGroup.CMA.setPermission(Perm.FREEZE_COMMAND, false, true); + PermissionGroup.ADMIN.setPermission(Perm.FREEZE_COMMAND, true, true); + PermissionGroup.CMOD.setPermission(Perm.UNFREEZE_COMMAND, false, true); + PermissionGroup.CMA.setPermission(Perm.UNFREEZE_COMMAND, false, true); + PermissionGroup.ADMIN.setPermission(Perm.UNFREEZE_COMMAND, true, true); + PermissionGroup.CMOD.setPermission(Perm.NOTIFY, false, true); + PermissionGroup.CMA.setPermission(Perm.NOTIFY, false, true); + PermissionGroup.ADMIN.setPermission(Perm.NOTIFY, true, true); + PermissionGroup.CONTENT.setPermission(Perm.PANIC_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PANIC_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new FreezeCommand(this)); + addCommand(new UnfreezeCommand(this)); + addCommand(new PanicCommand(this)); + } + + @EventHandler(priority = EventPriority.LOW) + public void onQuit(PlayerQuitEvent event) + { + Float walkSpeed = _frozen.remove(event.getPlayer().getUniqueId()); + if (walkSpeed != null) + { + event.getPlayer().setWalkSpeed(walkSpeed); + event.getPlayer().removePotionEffect(PotionEffectType.JUMP); + for (Player staff : UtilServer.GetPlayers()) + { + if (_clientManager.Get(staff).hasPermission(Perm.NOTIFY)) + { + UtilPlayer.message(staff, F.main(getName(), F.elem(event.getPlayer().getName()) + " has logged out while frozen!")); + } + } + } + + walkSpeed = _panic.remove(event.getPlayer().getUniqueId()); + if (walkSpeed != null) + { + event.getPlayer().setWalkSpeed(walkSpeed); + event.getPlayer().removePotionEffect(PotionEffectType.JUMP); + } + } + + @EventHandler + public void onMove(PlayerMoveEvent event) + { + if ((isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) && UtilMath.offset2d(event.getFrom().getBlock().getLocation(), event.getTo().getBlock().getLocation()) >= 1) + { + event.setCancelled(true); + event.getPlayer().teleport(event.getFrom().getBlock().getLocation().add(0, 0.5, 0)); + } + } + + @EventHandler + public void onDisplayFreezeMessage(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + for (UUID frozenUUID : _frozen.keySet()) + { + Player frozen = Bukkit.getPlayer(frozenUUID); + if (Recharge.Instance.use(frozen, "Freeze Message", FREEZE_MESSAGE_INTERVAL, false, false)) + { + String border = C.cGray + C.Strike + "-----------------------------------------------------"; + String sq = "\u2589"; + + UtilPlayer.message(frozen, border); + UtilPlayer.message(frozen, C.Reset + ""); + UtilPlayer.message(frozen, C.cWhite + sq + sq + sq + sq + C.cRed + sq + C.cWhite + sq + sq + sq + sq); + UtilPlayer.message(frozen, C.cWhite + sq + sq + sq + C.cRed + sq + C.cBlack + sq + C.cRed + sq + C.cWhite + sq + sq + sq); + UtilPlayer.message(frozen, C.cWhite + sq + sq + C.cRed + sq + C.cGold + sq + C.cBlack + sq + C.cGold + sq + C.cRed + sq + C.cWhite + sq + sq); + UtilPlayer.message(frozen, C.cWhite + sq + sq + C.cRed + sq + C.cGold + sq + C.cBlack + sq + C.cGold + sq + C.cRed + sq + C.cWhite + sq + sq); + UtilPlayer.message(frozen, C.cWhite + sq + sq + C.cRed + sq + C.cGold + sq + C.cBlack + sq + C.cGold + sq + C.cRed + sq + C.cWhite + sq + sq); + UtilPlayer.message(frozen, C.cWhite + sq + C.cRed + sq + C.cGold + sq + sq + sq + C.cGold + sq + sq + C.cRed + sq + C.cWhite + sq); + UtilPlayer.message(frozen, C.cRed + sq + C.cGold + sq + sq + sq + C.cBlack + sq + C.cGold + sq + sq + sq + C.cRed + sq); + UtilPlayer.message(frozen, C.cRed + sq + sq + sq + sq + sq + sq + sq + sq + sq); + UtilPlayer.message(frozen, C.Reset + ""); + UtilPlayer.message(frozen, C.cRed + "You have been frozen by a staff member!"); + UtilPlayer.message(frozen, C.cRed + "Do not log out or you will be banned!"); + UtilPlayer.message(frozen, C.Reset + ""); + UtilPlayer.message(frozen, border); + } + } + } + + @EventHandler + public void handleMobs(EntityTargetLivingEntityEvent event) + { + if (event.getTarget() instanceof Player) + { + Player player = (Player) event.getTarget(); + if (isFrozen(player) || isPanicking(player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + Player damager = event.GetDamagerPlayer(event.GetCause() == DamageCause.PROJECTILE); + Player damagee = event.GetDamageePlayer(); + + if (damager != null && (isFrozen(damager) || isPanicking(damager))) + { + event.SetCancelled("Frozen Attacker"); + UtilPlayer.message(damager, F.main(getName(), "You cannot attack others while frozen!")); + } + if (damagee != null && (isFrozen(damagee) || isPanicking(damagee))) + { + event.SetCancelled("Frozen Damagee"); + if (damager != null) + { + UtilPlayer.message(damager, F.main(getName(), "You cannot attack " + F.elem(damagee.getName()) + " while they are frozen!")); + } + } + } + + @EventHandler + public void onUseSkill(SkillTriggerEvent event) + { + if (isFrozen(event.GetPlayer()) || isPanicking(event.GetPlayer())) + { + event.SetCancelled(true); + UtilPlayer.message(event.GetPlayer(), F.main(getName(), "You cannot use " + F.skill(event.GetSkillName()) + " while frozen!")); + } + } + + @EventHandler + public void onBreak(BlockBreakEvent event) + { + if (isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot break blocks while frozen!")); + } + } + + @EventHandler + public void onPlace(BlockPlaceEvent event) + { + if (isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot place blocks while frozen!")); + } + } + + @EventHandler + public void onTpHome(ClansCommandExecutedEvent event) + { + if (isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot use that command while frozen!")); + } + } + + @EventHandler + public void onDropItem(PlayerDropItemEvent event) + { + if (isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot drop items while frozen!")); + } + } + + @EventHandler + public void onPickupItem(PlayerPickupItemEvent event) + { + if (isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot pick up items while frozen!")); + } + } + + @EventHandler + public void onOpenContainer(PlayerInteractEvent event) + { + if ((isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) && event.getClickedBlock() != null && CONTAINERS.contains(event.getClickedBlock().getType())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot open containers while frozen!")); + } + } + + @EventHandler + public void onOpenDoor(IronDoorOpenEvent event) + { + if (isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot use doors while frozen!")); + } + } + + @EventHandler + public void onToggleFlight(PlayerToggleFlightEvent event) + { + if ((isFrozen(event.getPlayer()) || isPanicking(event.getPlayer())) && event.isFlying()) + { + event.setCancelled(true); + } + } + + /** + * Checks if a player is frozen + * @param player The player to check + * @return Whether the player is frozen + */ + public boolean isFrozen(Player player) + { + return _frozen.containsKey(player.getUniqueId()); + } + + /** + * Checks if a player is panicking + * @param player The player to check + * @return Whether the player is panicking + */ + public boolean isPanicking(Player player) + { + return _panic.containsKey(player.getUniqueId()); + } + + /** + * Enters a player into panic mode + * @param player The player who is panicking + */ + public void panic(Player player) + { + _panic.put(player.getUniqueId(), _frozen.getOrDefault(player.getUniqueId(), player.getWalkSpeed())); + player.setFlying(false); + player.setWalkSpeed(0); + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10)); + if (!UtilServer.isTestServer()) + { + SlackMessage message = new SlackMessage("Clans Panic System", "crossed_swords", player.getName() + " has entered panic mode on " + UtilServer.getServerName() + "!"); + SlackAPI.getInstance().sendMessage(SlackTeam.CLANS, "#urgent", message, true); + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", message, true); + SlackAPI.getInstance().sendMessage(SlackTeam.SOCIAL_MEDIA, "#streams-announcements", message, true); + } + for (Player alert : UtilServer.GetPlayers()) + { + if (_clientManager.Get(alert).hasPermission(Perm.NOTIFY)) + { + UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has entered panic mode!")); + } + if (alert.getName().equals(player.getName())) + { + UtilPlayer.message(alert, F.main(getName(), "You have entered panic mode!")); + } + } + } + + /** + * Removes a player from panic mode + * @param player The player to unpanic + */ + public void unpanic(Player player) + { + Float walkSpeed = _panic.remove(player.getUniqueId()); + if (walkSpeed != null) + { + if (!_frozen.containsKey(player.getUniqueId())) + { + player.setWalkSpeed(walkSpeed); + player.removePotionEffect(PotionEffectType.JUMP); + } + if (!UtilServer.isTestServer()) + { + SlackMessage message = new SlackMessage("Clans Panic System", "crossed_swords", player.getName() + " has exited panic mode on " + UtilServer.getServerName() + "!"); + SlackAPI.getInstance().sendMessage(SlackTeam.CLANS, "#urgent", message, true); + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", message, true); + SlackAPI.getInstance().sendMessage(SlackTeam.SOCIAL_MEDIA, "#streams-announcements", message, true); + } + for (Player alert : UtilServer.GetPlayers()) + { + if (_clientManager.Get(alert).hasPermission(Perm.NOTIFY)) + { + UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has exited panic mode!")); + } + if (alert.getName().equals(player.getName())) + { + UtilPlayer.message(alert, F.main(getName(), "You have exited panic mode!")); + } + } + } + } + + /** + * Freezes a player + * @param player The player to freeze + * @param staff The staff member who froze them + */ + public void freeze(Player player, Player staff) + { + _frozen.put(player.getUniqueId(), _panic.getOrDefault(player.getUniqueId(), player.getWalkSpeed())); + player.setFlying(false); + player.setWalkSpeed(0); + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10)); + for (Player alert : UtilServer.GetPlayers()) + { + if (_clientManager.Get(alert).hasPermission(Perm.NOTIFY)) + { + UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has been frozen by " + F.elem(staff.getName()) + "!")); + } + } + } + + /** + * Unfreezes a player + * @param player The player to unfreeze + * @param staff The staff member who unfroze them + */ + public void unfreeze(Player player, Player staff) + { + Float walkSpeed = _frozen.remove(player.getUniqueId()); + if (walkSpeed != null) + { + if (!_panic.containsKey(player.getUniqueId())) + { + player.setWalkSpeed(walkSpeed); + player.removePotionEffect(PotionEffectType.JUMP); + } + for (Player alert : UtilServer.GetPlayers()) + { + if (_clientManager.Get(alert).hasPermission(Perm.NOTIFY)) + { + UtilPlayer.message(alert, F.main(getName(), F.elem(player.getName()) + " has been unfrozen by " + F.elem(staff.getName()) + "!")); + continue; + } + if (alert.getName().equals(player.getName())) + { + UtilPlayer.message(alert, F.main(getName(), "You have been unfrozen!")); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/FreezeCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/FreezeCommand.java new file mode 100644 index 00000000..bc5f75d1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/FreezeCommand.java @@ -0,0 +1,43 @@ +package mineplex.game.clans.clans.freeze.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.freeze.ClansFreezeManager; + +/** + * Command to freeze players + */ +public class FreezeCommand extends CommandBase +{ + public FreezeCommand(ClansFreezeManager plugin) + { + super(plugin, ClansFreezeManager.Perm.FREEZE_COMMAND, "freeze"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length < 1) + { + UtilPlayer.message(caller, C.cBlue + "/freeze " + C.cGray + " - " + C.cYellow + "Freezes a player, restricting their movement and ability to interact with the game."); + } + else if (args.length > 0) + { + Player target = UtilPlayer.searchOnline(caller, args[0], true); + if (target == null) + { + return; + } + if (Plugin.isFrozen(target)) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), F.elem(args[0]) + " is already frozen!")); + return; + } + Plugin.freeze(target, caller); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/PanicCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/PanicCommand.java new file mode 100644 index 00000000..1e60c10a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/PanicCommand.java @@ -0,0 +1,30 @@ +package mineplex.game.clans.clans.freeze.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.clans.freeze.ClansFreezeManager; + +/** + * Command to enter panic mode + */ +public class PanicCommand extends CommandBase +{ + public PanicCommand(ClansFreezeManager plugin) + { + super(plugin, ClansFreezeManager.Perm.PANIC_COMMAND, "panic"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (Plugin.isPanicking(caller)) + { + Plugin.unpanic(caller); + } + else + { + Plugin.panic(caller); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/UnfreezeCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/UnfreezeCommand.java new file mode 100644 index 00000000..a1de3c01 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/freeze/commands/UnfreezeCommand.java @@ -0,0 +1,43 @@ +package mineplex.game.clans.clans.freeze.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.freeze.ClansFreezeManager; + +/** + * Command to unfreeze players + */ +public class UnfreezeCommand extends CommandBase +{ + public UnfreezeCommand(ClansFreezeManager plugin) + { + super(plugin, ClansFreezeManager.Perm.UNFREEZE_COMMAND, "unfreeze"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length < 1) + { + UtilPlayer.message(caller, C.cBlue + "/unfreeze " + C.cGray + " - " + C.cYellow + "Unfreezes a player, restoring their movement and ability to interact with the game."); + } + else if (args.length > 0) + { + Player target = UtilPlayer.searchOnline(caller, args[0], true); + if (target == null) + { + return; + } + if (!Plugin.isFrozen(target)) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), F.elem(args[0]) + " is not frozen!")); + return; + } + Plugin.unfreeze(target, caller); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/ClanIcon.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/ClanIcon.java new file mode 100644 index 00000000..118549e9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/ClanIcon.java @@ -0,0 +1,35 @@ +package mineplex.game.clans.clans.gui; + +import org.bukkit.Material; + +public enum ClanIcon +{ + JOIN(Material.PRISMARINE, (byte) 1), + LEAVE(Material.PRISMARINE, (byte) 2), + TERRITORY(Material.PRISMARINE, (byte) 0), + MEMBER(Material.WATER_BUCKET, (byte) 0), + COMMANDS(Material.LAVA_BUCKET, (byte) 0), + ENERGY(Material.SEA_LANTERN, (byte) 0), + CASTLE(Material.RECORD_9, (byte) 0), + WAR(Material.RECORD_11, (byte) 0), + ALLIANCE(Material.RECORD_10, (byte) 0); + + private Material _material; + private byte _data; + + ClanIcon(Material material, byte data) + { + _material = material; + _data = data; + } + + public Material getMaterial() + { + return _material; + } + + public byte getData() + { + return _data; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/ClanShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/ClanShop.java new file mode 100644 index 00000000..7b0285d8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/ClanShop.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.clans.gui; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.page.ClanMainPage; +import mineplex.game.clans.clans.gui.page.ClanWhoPage; + +public class ClanShop extends ShopBase +{ + public ClanShop(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "ClansShop"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new ClanMainPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } + + public void openClanWho(Player player, ClanInfo clan) + { + openPageForPlayer(player, new ClanWhoPage(getPlugin(), this, getClientManager(), getDonationManager(), player, clan, false)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddAllyButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddAllyButton.java new file mode 100644 index 00000000..0ffc8673 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddAllyButton.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; +import mineplex.core.shop.item.IButton; + +public class ClanAddAllyButton implements IButton +{ + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.AddAlly)).isCancelled()) + return; + + player.closeInventory(); + JsonMessage message = new JsonMessage(C.cRed + C.Bold + "Click here to add an Ally").click(ClickEvent.SUGGEST_COMMAND, "/c ally "); + message.sendToPlayer(player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddTrustedButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddTrustedButton.java new file mode 100644 index 00000000..6a8d8a55 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddTrustedButton.java @@ -0,0 +1,26 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; +import mineplex.core.shop.item.IButton; + +public class ClanAddTrustedButton implements IButton +{ + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.AddTrusted)).isCancelled()) + return; + + player.closeInventory(); + + JsonMessage message = new JsonMessage(C.cRed + C.Bold + "Click here to trust a clan").click(ClickEvent.SUGGEST_COMMAND, "/c trust "); + message.sendToPlayer(player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddWarButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddWarButton.java new file mode 100644 index 00000000..d0faaa72 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanAddWarButton.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; +import mineplex.core.shop.item.IButton; + +public class ClanAddWarButton implements IButton +{ + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.AddWar)).isCancelled()) + return; + player.closeInventory(); + + JsonMessage message = new JsonMessage(C.cRed + C.Bold + "Click here to war a clan").click(ClickEvent.SUGGEST_COMMAND, "/war "); + message.sendToPlayer(player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanButton.java new file mode 100644 index 00000000..055a4eed --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanButton.java @@ -0,0 +1,69 @@ +package mineplex.game.clans.clans.gui.button; + +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public abstract class ClanButton implements IButton +{ + private ClanShop _shop; + protected ClansManager _clansManager; + private Player _player; + private ClanInfo _clanInfo; + private ClanRole _clanRole; + + public ClanButton(ClanShop shop, ClansManager clansManager, Player player, ClanInfo clanInfo, ClanRole clanRole) + { + _shop = shop; + _clansManager = clansManager; + _player = player; + _clanInfo = clanInfo; + _clanRole = clanRole; + } + + public ClansManager getClansManager() + { + return _clansManager; + } + + public Player getPlayer() + { + return _player; + } + + public ClanInfo getClanInfo() + { + return _clanInfo; + } + + public ClanRole getClanRole() + { + return _clanRole; + } + + public ClanShop getShop() + { + return _shop; + } + + protected void displayText(String header, String message) + { + UtilTextMiddle.display(header, message, _player); + } + + protected void displayClan(String header, String message, boolean displayForClicker) + { + for (Player player : _clanInfo.getOnlinePlayers()) + { + if (displayForClicker || !player.equals(getPlayer())) + UtilTextMiddle.display(header, message, player); + } + +// _clansManager.messageClan(_clanInfo, message); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanCreateButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanCreateButton.java new file mode 100644 index 00000000..e6fa820b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanCreateButton.java @@ -0,0 +1,33 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +public class ClanCreateButton implements IButton +{ + public ClanCreateButton() + { + + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Create)).isCancelled()) + { + return; + } + + TextComponent message = new TextComponent("Click Here to create a Clan!"); + message.setColor(ChatColor.AQUA); + message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/c create ")); + player.spigot().sendMessage(message); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanDisbandButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanDisbandButton.java new file mode 100644 index 00000000..6165d054 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanDisbandButton.java @@ -0,0 +1,28 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public class ClanDisbandButton extends ClanButton +{ + public ClanDisbandButton(ClanShop shop, ClansManager clansManager, Player player, ClanInfo clanInfo, ClanRole clanRole) + { + super(shop, clansManager, player, clanInfo, clanRole); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Disband)).isCancelled()) + return; + getPlayer().closeInventory(); + getClansManager().getClanUtility().delete(getPlayer()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanEnergyButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanEnergyButton.java new file mode 100644 index 00000000..20038637 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanEnergyButton.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public class ClanEnergyButton extends ClanButton +{ + public ClanEnergyButton(ClanShop shop, ClansManager clansManager, Player player, ClanInfo clanInfo, ClanRole clanRole) + { + super(shop, clansManager, player, clanInfo, clanRole); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Energy)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanInviteButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanInviteButton.java new file mode 100644 index 00000000..f32e20b1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanInviteButton.java @@ -0,0 +1,32 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.donation.DonationManager; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; +import mineplex.game.clans.clans.gui.page.ClanInvitePage; + +public class ClanInviteButton extends ClanButton +{ + private DonationManager _donationManager; + + public ClanInviteButton(ClanShop shop, ClansManager clansManager, DonationManager donationManager, Player player, ClanInfo clanInfo, ClanRole clanRole) + { + super(shop, clansManager, player, clanInfo, clanRole); + _donationManager = donationManager; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Invite)).isCancelled()) + return; + getShop().openPageForPlayer(getPlayer(), new ClanInvitePage(getClansManager(), getShop(), getClansManager().getClientManager(), _donationManager, player)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanJoinButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanJoinButton.java new file mode 100644 index 00000000..fb8c7862 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanJoinButton.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; + +public class ClanJoinButton implements IButton +{ + private ClansManager _clansManager; + private ClanInfo _clanInfo; + + public ClanJoinButton(ClansManager clansManager, ClanInfo clanInfo) + { + _clansManager = clansManager; + _clanInfo = clanInfo; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Join)).isCancelled()) + return; + player.closeInventory(); + _clansManager.getClanUtility().join(player, _clanInfo); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanLeaveButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanLeaveButton.java new file mode 100644 index 00000000..fbf261c8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanLeaveButton.java @@ -0,0 +1,41 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public class ClanLeaveButton extends ClanButton +{ + public ClanLeaveButton(ClanShop shop, ClansManager clansManager, Player player, ClanInfo clanInfo, ClanRole clanRole) + { + super(shop, clansManager, player, clanInfo, clanRole); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if(clickType.equals(ClickType.SHIFT_RIGHT)) //disband + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Disband)).isCancelled()) + return; + + getPlayer().closeInventory(); + getClansManager().getClanUtility().delete(getPlayer()); + + }else if(clickType.equals(ClickType.SHIFT_LEFT)) //leave + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Leave)).isCancelled()) + return; + + getPlayer().closeInventory(); + getClansManager().getClanUtility().leave(getPlayer()); + } + + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanMemeberButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanMemeberButton.java new file mode 100644 index 00000000..0570693d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanMemeberButton.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; +import mineplex.game.clans.clans.gui.page.ClanMainPage; + +public class ClanMemeberButton extends ClanButton +{ + private ClanMainPage _page; + private String _other; + + public ClanMemeberButton(ClanShop shop, ClansManager clansManager, Player player, ClanInfo clanInfo, ClanRole clanRole, ClanMainPage page, String other) + { + super(shop, clansManager, player, clanInfo, clanRole); + _other = other; + _page = page; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Member)).isCancelled()) + return; + if (clickType == ClickType.LEFT) + { + // Promote + getClansManager().getClanUtility().promote(getPlayer(), _other); + _page.refresh(); + } + else if (clickType == ClickType.RIGHT) + { + // Demote + getClansManager().getClanUtility().demote(getPlayer(), _other); + _page.refresh(); + } + else if (clickType == ClickType.SHIFT_RIGHT) + { + // Kick + getClansManager().getClanUtility().kick(getPlayer(), _other); + _page.refresh(); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanRelationsButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanRelationsButton.java new file mode 100644 index 00000000..13497350 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanRelationsButton.java @@ -0,0 +1,8 @@ +package mineplex.game.clans.clans.gui.button; + +/** + * Created by phina on 10/31/2015. + */ +public class ClanRelationsButton +{ +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanTerritoryButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanTerritoryButton.java new file mode 100644 index 00000000..ebcff061 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanTerritoryButton.java @@ -0,0 +1,79 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public class ClanTerritoryButton extends ClanButton +{ + public ClanTerritoryButton(ClanShop shop, ClansManager clansManager, Player player, ClanInfo clanInfo, ClanRole clanRole) + { + super(shop, clansManager, player, clanInfo, clanRole); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Territory)).isCancelled()) + return; + if (_clansManager.getNetherManager().isInNether(player)) + { + UtilPlayer.message(player, F.main(_clansManager.getNetherManager().getName(), "You cannot manage your clan's territory while in " + F.clansNether("The Nether") + "!")); + player.closeInventory(); + return; + } + if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + UtilPlayer.message(player, F.main(_clansManager.getWorldEvent().getRaidManager().getName(), "You cannot manage your clan's territory while in a raid!")); + player.closeInventory(); + return; + } + + if (clickType == ClickType.LEFT) + { + player.closeInventory(); + + Chunk chunk = player.getLocation().getChunk(); + String chunkName = UtilWorld.chunkToStrClean(chunk); + if (getClansManager().getClanUtility().claim(player)) + { + displayText(C.cGreen + "Territory", "You claimed the chunk " + chunkName); + displayClan(C.cGreen + "Territory", C.cYellow + getPlayer().getName() + ChatColor.RESET + " claimed the chunk " + chunkName, false); + } + } + else if (clickType == ClickType.SHIFT_LEFT) + { + player.closeInventory(); + + Chunk chunk = player.getLocation().getChunk(); + String chunkName = UtilWorld.chunkToStrClean(chunk); + if (getClansManager().getClanUtility().unclaim(player, player.getLocation().getChunk())) + { + displayText(C.cGreen + "Territory", "You unclaimed the chunk " + chunkName); + displayClan(C.cGreen + "Territory", C.cYellow + getPlayer().getName() + ChatColor.RESET + " unclaimed the chunk " + chunkName, false); + } + } + else if (clickType == ClickType.SHIFT_RIGHT && getClanRole() == ClanRole.LEADER) + { + player.closeInventory(); + + if (getClansManager().getClanUtility().unclaimAll(player)) + { + displayText(C.cGreen + "Territory", "You unclaimed all chunks"); + displayClan(C.cGreen + "Territory", C.cYellow + getPlayer().getName() + ChatColor.RESET + " unclaimed all chunks", false); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanWhoButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanWhoButton.java new file mode 100644 index 00000000..ce482aee --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/ClanWhoButton.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans.gui.button; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; +import mineplex.core.shop.item.IButton; + +public class ClanWhoButton implements IButton +{ + @Override + public void onClick(Player player, ClickType clickType) + { + if (UtilServer.CallEvent(new ClansButtonClickEvent(player, ClansButtonClickEvent.ButtonType.Who)).isCancelled()) + return; + player.closeInventory(); + + JsonMessage message = new JsonMessage(C.cRed + C.Bold + "Click here to lookup a clan").click(ClickEvent.SUGGEST_COMMAND, "/c who "); + message.sendToPlayer(player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/MemberManagementButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/MemberManagementButton.java new file mode 100644 index 00000000..b9c261a1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/button/MemberManagementButton.java @@ -0,0 +1,8 @@ +package mineplex.game.clans.clans.gui.button; + +/** + * Created by phina on 10/31/2015. + */ +public class MemberManagementButton +{ +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/events/ClansButtonClickEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/events/ClansButtonClickEvent.java new file mode 100644 index 00000000..844a1159 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/events/ClansButtonClickEvent.java @@ -0,0 +1,67 @@ +package mineplex.game.clans.clans.gui.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ClansButtonClickEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private ButtonType _type; + + private boolean _cancelled; + + public ClansButtonClickEvent(Player player, ButtonType type) + { + _player = player; + _type = type; + } + + public Player getPlayer() + { + return _player; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public ButtonType getButtonType() { + return _type; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + + public enum ButtonType + { + AddAlly, + AddTrusted, + AddWar, + Create, + Disband, + Energy, + Invite, + Join, + Leave, + Member, + Territory, + Who; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanInvitePage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanInvitePage.java new file mode 100644 index 00000000..b7dd889e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanInvitePage.java @@ -0,0 +1,81 @@ +package mineplex.game.clans.clans.gui.page; + +import java.util.ArrayList; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilSkull; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public class ClanInvitePage extends ClanPageBase +{ + public ClanInvitePage(ClansManager plugin, ClanShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, "Invite Players", player, 54); + + buildPage(); + } + + @Override + public void buildNoClan() + { + + } + + @Override + public void buildClan(ClanInfo clanInfo, ClanRole clanRole) + { + int index = 9; + for (Player player : UtilServer.getSortedPlayers()) + { + if (index <= 54 && getPlugin().getClan(player) == null && !_plugin.getIncognitoManager().Get(player).Status) + { + addPlayerButton(index, player, clanInfo); + index++; + } + } + + if (index == 9) + { + // No players online to join! + String[] lore = new String[] { C.Reset + "There are no players online who", C.Reset + "are not in a clan already!" }; + ShopItem shopItem = new ShopItem(Material.BARRIER, "No Players!", lore,1, true, false); + addItem(22, shopItem); + } + + addBackButton(); + } + + private void addPlayerButton(int slot, final Player target, final ClanInfo clan) + { + String itemName = C.cGreenB + target.getName(); + ArrayList lore = new ArrayList(5); + lore.add(" "); + lore.add(" "); + lore.add(ChatColor.RESET + C.cGray + "Left Click " + C.cWhite + "Invite Player"); + + ItemStack item = UtilSkull.getPlayerHead(target.getName(), itemName, lore); + + addButton(slot, item, new IButton() + { + @Override + public void onClick(Player player, ClickType clickType) + { + getPlugin().getClanUtility().invite(getPlayer(), clan, target); + } + }); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanJoinPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanJoinPage.java new file mode 100644 index 00000000..7134328f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanJoinPage.java @@ -0,0 +1,59 @@ +package mineplex.game.clans.clans.gui.page; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.ShopItem; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; +import mineplex.game.clans.clans.gui.button.ClanJoinButton; + +public class ClanJoinPage extends ClanPageBase +{ + public ClanJoinPage(ClansManager plugin, ClanShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, "Join Clan", player, 54); + + buildPage(); + } + + @Override + public void buildNoClan() + { + int currentIndex = 9; + + for (ClanInfo clanInfo : getPlugin().getClanMap().values()) + { + if (clanInfo.isInvited(getPlayer().getName())) + { + addInvitation(currentIndex, clanInfo); + currentIndex++; + } + } + + if (currentIndex == 9) + { + // No invitations :( + ShopItem shopItem = new ShopItem(Material.BOOK, "You have no Clan Invitations!", new String[] {}, 1, true, false); + setItem(22, shopItem); + } + + addBackButton(); + } + + private void addInvitation(int index, ClanInfo clanInfo) + { + ShopItem shopItem = new ShopItem(Material.BOOK_AND_QUILL, clanInfo.getName(), new String[] {}, 1, false, false); + addButton(index, shopItem, new ClanJoinButton(getPlugin(), clanInfo)); + } + + @Override + public void buildClan(ClanInfo clanInfo, ClanRole clanRole) + { + // Nothing + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanMainPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanMainPage.java new file mode 100644 index 00000000..ee6361d7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanMainPage.java @@ -0,0 +1,364 @@ +package mineplex.game.clans.clans.gui.page; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.TreeSet; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilSkull; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansPlayer; +import mineplex.game.clans.clans.ClansPlayerComparator; +import mineplex.game.clans.clans.gui.ClanIcon; +import mineplex.game.clans.clans.gui.ClanShop; +import mineplex.game.clans.clans.gui.button.ClanCreateButton; +import mineplex.game.clans.clans.gui.button.ClanEnergyButton; +import mineplex.game.clans.clans.gui.button.ClanInviteButton; +import mineplex.game.clans.clans.gui.button.ClanLeaveButton; +import mineplex.game.clans.clans.gui.button.ClanMemeberButton; +import mineplex.game.clans.clans.gui.button.ClanTerritoryButton; +import mineplex.game.clans.clans.gui.button.ClanWhoButton; +import mineplex.game.clans.core.war.ClanWarData; + +public class ClanMainPage extends ClanPageBase +{ + private static boolean USE_RESOURCE_ICONS = true; + + public ClanMainPage(ClansManager plugin, ClanShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, "Manage Clan", player, 54); + + buildPage(); + } + + @Override + public void buildNoClan() + { + // Clan Create + ShopItem clanCreate = new ShopItem(Material.BOOK_AND_QUILL, "Create Clan", new String[] {C.cGray + "To create a clan type", C.cRed + "/c create "}, 1, false, false); + addButton(21, clanCreate, new ClanCreateButton()); + + // Clan Join + ShopItem clanJoin = new ShopItem(ClanIcon.JOIN.getMaterial(), ClanIcon.JOIN.getData(), "Join Clan", new String[] {}, 1, false, false); + addButton(23, clanJoin, new IButton() + { + @Override + public void onClick(Player player, ClickType clickType) + { + getShop().openPageForPlayer(getPlayer(), new ClanJoinPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), getPlayer())); + } + }); + } + + @Override + public void buildClan(final ClanInfo clanInfo, ClanRole clanRole) + { + // Invites + { + String inviteName = "Invites"; + Material inviteMaterial = USE_RESOURCE_ICONS ? ClanIcon.JOIN.getMaterial() : Material.RED_ROSE; + byte inviteDate = USE_RESOURCE_ICONS ? ClanIcon.JOIN.getData() : 0; + int size = clanInfo.getSize(); + int maxSize = clanInfo.getMaxSize(); + ArrayList inviteLore = new ArrayList(); + inviteLore.add(" "); + inviteLore.add(C.Reset + C.cGray + "Clans can have a max size of " + C.cYellow + maxSize + C.cGray + " members"); + inviteLore.add(C.Reset + C.cGray + "You currently have " + C.cYellow + size + C.cGray + " members"); + inviteLore.add(C.Reset + C.cGray + "More members in your clan will allow you to"); + inviteLore.add(C.Reset + C.cGray + "claim more land, but it will also increase"); + inviteLore.add(C.Reset + C.cGray + "your Energy drain per minute."); + if (clanRole.has(ClanRole.ADMIN)) + { + inviteLore.add(" "); + inviteLore.add(C.Reset + C.cYellow + "Left Click " + C.cWhite + "Invite Player"); + } + + ShopItem inviteItem = new ShopItem(inviteMaterial, inviteDate, inviteName, inviteLore.toArray(new String[0]), 1, false, false); + ClanInviteButton inviteButton = new ClanInviteButton(getShop(), getPlugin(), getDonationManager(), getPlayer(), clanInfo, clanRole); + addButton(0, inviteItem, inviteButton); + } + + // Territory + { + String territoryName = "Territory"; + Material territoryMaterial = USE_RESOURCE_ICONS ? ClanIcon.TERRITORY.getMaterial() : Material.GRASS; + byte territoryData = USE_RESOURCE_ICONS ? (byte) ClanIcon.TERRITORY.getData() : 0; + ArrayList territoryLore = new ArrayList(); + int claims = clanInfo.getClaims(); + int maxClaims = clanInfo.getClaimsMax(); + territoryLore.add(" "); + territoryLore.add(C.Reset + C.cGray + "Every land claim represents a 16x16 chunk"); + territoryLore.add(C.Reset + C.cGray + "Your clan can claim a maximum of " + C.cYellow + maxClaims + C.cGray + " chunks"); + territoryLore.add(C.Reset + C.cGray + "You currently have " + C.cYellow + claims + C.cGray + " chunk(s) claimed"); + territoryLore.add(C.Reset + C.cGray + "Increase max claims with more clan members"); + territoryLore.add(C.Reset + C.cGray + "Energy cost will increase with more land claimed"); + if (clanRole.has(ClanRole.ADMIN)) + { + territoryLore.add(" "); + territoryLore.add(ChatColor.RESET + C.cYellow + "Left Click " + C.cWhite + "Claim Land"); + territoryLore.add(ChatColor.RESET + C.cYellow + "Shift-Left Click " + C.cWhite + "Unclaim Land"); + if (clanRole.has(ClanRole.LEADER)) + { + territoryLore.add(ChatColor.RESET + C.cYellow + "Shift-Right Click " + C.cWhite + "Unclaim All Land"); + } + } + + ShopItem territoryItem = new ShopItem(territoryMaterial, territoryData, territoryName, territoryLore.toArray(new String[0]), 1, false, false); + ClanTerritoryButton territoryButton = new ClanTerritoryButton(getShop(), getPlugin(), getPlayer(), clanInfo, clanRole); + addButton(2, territoryItem, territoryButton); + } + + // Energy + { + String energyName = "Energy"; + Material energyMaterial = USE_RESOURCE_ICONS ? ClanIcon.ENERGY.getMaterial() : Material.GOLD_BLOCK; + byte energyData = USE_RESOURCE_ICONS ? ClanIcon.ENERGY.getData() : 0; + ArrayList energyLore = new ArrayList(); + energyLore.add(" "); + energyLore.add(C.Reset + C.cGray + "Energy is the currency used to upkeep"); + energyLore.add(C.Reset + C.cGray + "your clan. Energy drains over time and"); + energyLore.add(C.Reset + C.cGray + "you will need to refill it at the NPC in"); + energyLore.add(C.Reset + C.cGray + "the shops. More clan members and more land"); + energyLore.add(C.Reset + C.cGray + "increases the rate energy drains at."); + energyLore.add(" "); + energyLore.add(C.Reset + C.cYellow + "Energy " + C.cWhite + clanInfo.getEnergy() + "/" + clanInfo.getEnergyMax()); + if (clanInfo.getEnergyCostPerMinute() > 0) + energyLore.add(C.Reset + C.cYellow + "Energy Depletes " + C.cWhite + clanInfo.getEnergyLeftString()); + + ShopItem energyItem = new ShopItem(energyMaterial, energyData, energyName, energyLore.toArray(new String[0]), 1, false, false); + ClanEnergyButton energyButton = new ClanEnergyButton(getShop(), getPlugin(), getPlayer(), clanInfo, clanRole); + addButton(4, energyItem, energyButton); + } + + + // Leave + { + String leaveName = "Leave"; + Material leaveMaterial = USE_RESOURCE_ICONS ? ClanIcon.LEAVE.getMaterial() : Material.TNT; + byte leaveData = USE_RESOURCE_ICONS ? ClanIcon.LEAVE.getData() : 0; + ArrayList leaveLore = new ArrayList(); + leaveLore.add(" "); + if (clanRole.has(ClanRole.MEMBER)) + { + leaveLore.add(ChatColor.RESET + C.cYellow + "Shift-Left Click " + C.cWhite + "Leave Clan"); + } + if (clanRole.has(ClanRole.LEADER)) + { + leaveLore.add(ChatColor.RESET + C.cYellow + "Shift-Right Click " + C.cWhite + "Disband Clan"); + } + + ShopItem leaveItem = new ShopItem(leaveMaterial, leaveData, leaveName, leaveLore.toArray(new String[0]), 1, false, false); + ClanLeaveButton leaveButton = new ClanLeaveButton(getShop(), getPlugin(), getPlayer(), clanInfo, clanRole); + addButton(6, leaveItem, leaveButton); + } + + // Commands + { + String commandsName = "Commands"; + Material commandsMaterial = USE_RESOURCE_ICONS ? ClanIcon.COMMANDS.getMaterial() : Material.PAPER; + byte commandsData = USE_RESOURCE_ICONS ? ClanIcon.COMMANDS.getData() : 0; + ArrayList commandsLore = new ArrayList(); + commandsLore.add(" "); + commandsLore.add(ChatColor.RESET + C.cYellow + "/c help " + C.cWhite + "Lists Clans Commands"); + commandsLore.add(ChatColor.RESET + C.cYellow + "/c ally " + C.cWhite + "Request Ally"); + commandsLore.add(ChatColor.RESET + C.cYellow + "/c neutral " + C.cWhite + "Revoke Ally"); + commandsLore.add(ChatColor.RESET + C.cYellow + "/c sethome " + C.cWhite + "Set Home Bed"); + commandsLore.add(ChatColor.RESET + C.cYellow + "/c home " + C.cWhite + "Teleport to Home Bed"); + commandsLore.add(ChatColor.RESET + C.cYellow + "/map " + C.cWhite + "Give yourself a World Map"); + + ShopItem commandsItem = new ShopItem(commandsMaterial, commandsData, commandsName, commandsLore.toArray(new String[0]), 1, false, false); + setItem(8, commandsItem); + } + + // Players + { + int slot = 18; + for (ClansPlayer clansPlayer : UtilAlg.sortSet(clanInfo.getMembers().values(), new ClansPlayerComparator())) + { + addPlayerButton(slot, clansPlayer, clanInfo, clanRole); + slot++; + } + } + + // Allies + { + // We need to sort the ally set in the order of players online! + TreeSet allySet = new TreeSet(new Comparator() + { + @Override + public int compare(ClanInfo o1, ClanInfo o2) + { + return o1.getOnlinePlayers().size() - o2.getOnlinePlayers().size(); + } + }); + + for (String allyName : clanInfo.getAllyMap().keySet()) + { + ClanInfo ally = getPlugin().getClan(allyName); + if (ally != null) + { + allySet.add(ally); + } + } + + int slot = 36; + for (ClanInfo ally : allySet) + { + addAllyButton(slot, ally); + slot++; + } + } + + // Wars + { + TreeSet warSet = new TreeSet(new Comparator() + { + @Override + public int compare(ClanWarData o1, ClanWarData o2) + { + return o1.getPoints(clanInfo.getName()) - o2.getPoints(clanInfo.getName()); + } + }); + + warSet.addAll(clanInfo.getWars()); + + Iterator descIterator = warSet.descendingIterator(); + Iterator ascIterator = warSet.iterator(); + + for (int i = 0; i < 4 && descIterator.hasNext(); i++) + { + ClanWarData data = descIterator.next(); + if (data.getPoints(clanInfo.getName()) <= 0) + break; + + int slot = 45 + i; + addWarButton(slot, clanInfo, data); + } + + for (int i = 0; i < 4 && ascIterator.hasNext(); i++) + { + ClanWarData data = ascIterator.next(); + if (data.getPoints(clanInfo.getName()) >= 0) + break; + + int slot = 53 - i; + addWarButton(slot, clanInfo, data); + } + + } + } + + private void addWarButton(int slot, ClanInfo clan, final ClanWarData clanWar) + { + String enemyName = clanWar.getClanA().equals(clan.getName()) ? clanWar.getClanB() : clanWar.getClanA(); + final ClanInfo enemy = getPlugin().getClan(enemyName); + if (enemy != null) + { + String itemName = enemyName; + Material material = USE_RESOURCE_ICONS ? ClanIcon.WAR.getMaterial() : Material.DIAMOND_SWORD; + byte data = USE_RESOURCE_ICONS ? ClanIcon.WAR.getData() : 0; + int warPoints = clanWar.getPoints(clan.getName()); + + ArrayList lore = new ArrayList(5); + lore.add(" "); + lore.add(C.Reset + C.cYellow + "War Points " + clan.getFormattedWarPoints(enemy)); + lore.add(" "); + lore.add(ChatColor.RESET + C.cGray + "Left Click " + C.cWhite + "Clan Info"); + + ShopItem shopItem = new ShopItem(material, data, itemName, lore.toArray(new String[0]), 0, false, false); + addButtonFakeCount(slot, shopItem, new IButton() + { + @Override + public void onClick(Player player, ClickType clickType) + { + getShop().openPageForPlayer(player, new ClanWhoPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), player, enemy, true)); + } + }, warPoints); + } + else + { + System.err.println("Could not find enemy clan: " + enemyName); + } + } + + private void addAllyButton(int slot, final ClanInfo ally) + { + String itemName = ally.getName(); + Material material = USE_RESOURCE_ICONS ? ClanIcon.ALLIANCE.getMaterial() : Material.EMERALD_BLOCK; + byte data = USE_RESOURCE_ICONS ? ClanIcon.ALLIANCE.getData() : 0; + ArrayList lore = new ArrayList(5); + lore.add(" "); + lore.add(ChatColor.RESET + C.cGray + "Left Click " + C.cWhite + "Clan Info"); + + ShopItem shopItem = new ShopItem(material, data, itemName, lore.toArray(new String[0]), 1, false, false); + addButtonFakeCount(slot, shopItem, new IButton() + { + @Override + public void onClick(Player player, ClickType clickType) + { + getShop().openPageForPlayer(player, new ClanWhoPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), player, ally, true)); + } + }, ally.getOnlinePlayers().size()); + } + + private void addPlayerButton(int slot, ClansPlayer clansPlayer, ClanInfo guiInfo, ClanRole guiRole) + { + ClanRole playerRole = clansPlayer.getRole(); + String itemName = (clansPlayer.isOnline() ? C.cGreenB : C.cRedB) + clansPlayer.getPlayerName(); + ArrayList lore = new ArrayList(5); + lore.add(" "); + lore.add(C.Reset + C.cYellow + "Role " + C.cWhite + clansPlayer.getRole().getFriendlyName()); + if (clansPlayer.isOnline()) + { + Player player = UtilPlayer.searchExact(clansPlayer.getUuid()); + if (player != null) + { + String loc = UtilWorld.locToStrClean(player.getLocation()); + lore.add(C.Reset + C.cYellow + "Location " + C.cWhite + loc); + // TODO Save join date? + } + } + // TODO Save last join date + + if (guiRole.has(ClanRole.ADMIN)) + { + lore.add(" "); + + if (!playerRole.has(ClanRole.LEADER) && guiRole.has(playerRole)) + { + lore.add(ChatColor.RESET + C.cYellow + "Left Click " + C.cWhite + "Promote"); + } + + if (!playerRole.has(ClanRole.LEADER) && guiRole.has(playerRole)) + { + lore.add(ChatColor.RESET + C.cYellow + "Right Click " + C.cWhite + "Demote"); + } + + if (!playerRole.has(ClanRole.LEADER)) + { + lore.add(ChatColor.RESET + C.cYellow + "Shift-Right Click " + C.cWhite + "Kick"); + } + } + + ItemStack item = UtilSkull.getPlayerHead(clansPlayer.isOnline() ? clansPlayer.getPlayerName() : "", itemName, lore); + + addButton(slot, item, new ClanMemeberButton(getShop(), getPlugin(), getPlayer(), guiInfo, guiRole, this, clansPlayer.getPlayerName())); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanPageBase.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanPageBase.java new file mode 100644 index 00000000..f4e781d5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanPageBase.java @@ -0,0 +1,64 @@ +package mineplex.game.clans.clans.gui.page; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanShop; + +public abstract class ClanPageBase extends ShopPageBase +{ + public ClanPageBase(ClansManager plugin, ClanShop shop, CoreClientManager clientManager, DonationManager donationManager, String name, Player player, int size) + { + super(plugin, shop, clientManager, donationManager, name, player, size); + } + + @Override + protected final void buildPage() + { + ClanInfo clanInfo = getPlugin().getClan(getPlayer()); + + if (clanInfo == null) + { + buildNoClan(); + } + else + { + ClanRole role = getPlugin().getClanUtility().getRole(getPlayer()); + buildClan(clanInfo, role); + } + } + + public abstract void buildNoClan(); + + public abstract void buildClan(ClanInfo clanInfo, ClanRole clanRole); + + protected void addBackButton() + { + addBackButton(4); + } + + protected void addBackButton(int slot) + { + addButton(slot, new ShopItem(Material.BED, C.cGray + " \u21FD Go Back", new String[]{}, 1, false), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + ShopPageBase mainPage = new ClanMainPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), getPlayer()); + + getShop().openPageForPlayer(getPlayer(), mainPage); + player.playSound(player.getLocation(), Sound.CLICK, 1, 1); + } + }); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanWhoPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanWhoPage.java new file mode 100644 index 00000000..e38ed4b1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/gui/page/ClanWhoPage.java @@ -0,0 +1,147 @@ +package mineplex.game.clans.clans.gui.page; + +import java.util.ArrayList; +import java.util.HashSet; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilSkull; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.ShopItem; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansPlayer; +import mineplex.game.clans.clans.ClansPlayerComparator; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.game.clans.clans.gui.ClanShop; +import mineplex.game.clans.clans.gui.ClanIcon; + +public class ClanWhoPage extends ClanPageBase +{ + private ClanInfo _lookupClan; + private boolean _showBackButton; + + public ClanWhoPage(ClansManager plugin, ClanShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player, ClanInfo lookupClan, boolean showBackButton) + { + super(plugin, shop, clientManager, donationManager, lookupClan.getName(), player, 45); + _lookupClan = lookupClan; + _showBackButton = showBackButton; + + buildPage(); + } + + @Override + public void buildNoClan() + { + build(null); + } + + @Override + public void buildClan(ClanInfo clanInfo, ClanRole clanRole) + { + build(clanInfo); + } + + private void build(ClanInfo clanInfo) + { + ClansUtility.ClanRelation relation = getPlugin().getClanUtility().rel(clanInfo, _lookupClan); + + // Main Clan Info + { + int slot = 4; + ArrayList lore = new ArrayList(); + lore.add(" "); + + // Basic Clan Info + lore.add(C.Reset + C.cYellow + "Founder " + C.cWhite + _lookupClan.getDesc()); + lore.add(C.Reset + C.cYellow + "Formed " + C.cWhite + UtilTime.convertString(System.currentTimeMillis() - _lookupClan.getDateCreated().getTime(), 1, UtilTime.TimeUnit.FIT) + " ago on " + UtilTime.when(_lookupClan.getDateCreated().getTime())); + lore.add(C.Reset + C.cYellow + "Members " + C.cWhite + _lookupClan.getOnlinePlayerCount() + "/" + _lookupClan.getMembers().size()); + lore.add(C.Reset + C.cYellow + "Territory " + C.cWhite + _lookupClan.getClaims() + "/" + _lookupClan.getClaimsMax()); + if (clanInfo != null) + { + lore.add(C.Reset + C.cYellow + "Your War Points " + C.cWhite + clanInfo.getFormattedWarPoints(_lookupClan)); + } + lore.add(" "); + + // Energy + lore.add(C.Reset + C.cYellow + "Energy " + C.cWhite + _lookupClan.getEnergy() + "/" + _lookupClan.getEnergyMax()); + if (_lookupClan.getEnergyCostPerMinute() > 0) + lore.add(C.Reset + C.cYellow + "Energy Depletes " + C.cWhite + _lookupClan.getEnergyLeftString()); + + lore.add(" "); + + // Allies + if (_lookupClan.getAllyMap().size() > 0) + { + String allySorted = ""; + HashSet allyUnsorted = new HashSet(); + + for (String allyName : _lookupClan.getAllyMap().keySet()) + allyUnsorted.add(allyName); + + for (String cur : UtilAlg.sortKey(allyUnsorted)) + allySorted += C.cGreen + cur + C.cWhite + ", "; + + lore.add(C.Reset + C.cYellow + "Allies"); + lore.add(" " + allySorted); + } + + // Self Clan Info + if (_lookupClan.equals(clanInfo)) + { + String clanHome = _lookupClan.getHome() == null ? "None" : UtilWorld.locToStrClean(_lookupClan.getHome()); + String generator = _lookupClan.getGenerator() == null ? "None" : "Yes"; + + lore.add(C.Reset + C.cYellow + "Clan Home " + C.cWhite + clanHome); + lore.add(C.Reset + C.cYellow + "TNT Generator " + C.cWhite + generator); + } + + ShopItem shopItem = new ShopItem(ClanIcon.CASTLE.getMaterial(), ClanIcon.CASTLE.getData(), _lookupClan.getName(), lore.toArray(new String[0]), 1, false, false); + setItem(slot, shopItem); + } + + + // Players + { + int slot = 18; + for (ClansPlayer player : UtilAlg.sortSet(_lookupClan.getMembers().values(), new ClansPlayerComparator())) + { + addPlayer(slot, player, relation == ClansUtility.ClanRelation.ALLY || relation == ClansUtility.ClanRelation.ALLY_TRUST || relation == ClansUtility.ClanRelation.SELF); + slot++; + } + } + + if (_showBackButton) + { + addBackButton(0); + } + } + + private void addPlayer(int slot, ClansPlayer clansPlayer, boolean showLocation) + { + String itemName = (clansPlayer.isOnline() ? C.cGreenB : C.cRedB) + clansPlayer.getPlayerName(); + ArrayList lore = new ArrayList(5); + lore.add(" "); + lore.add(C.Reset + C.cYellow + "Role " + C.cWhite + clansPlayer.getRole().getFriendlyName()); + if (showLocation && clansPlayer.isOnline()) + { + Player player = UtilPlayer.searchExact(clansPlayer.getUuid()); + if (player != null) + { + String loc = UtilWorld.locToStrClean(player.getLocation()); + lore.add(C.Reset + C.cYellow + "Location " + C.cWhite + loc); + } + } + + ItemStack item = UtilSkull.getPlayerHead(clansPlayer.isOnline() ? clansPlayer.getPlayerName() : "", itemName, lore); + setItem(slot, item); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/InvseeManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/InvseeManager.java new file mode 100644 index 00000000..59fbba87 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/InvseeManager.java @@ -0,0 +1,80 @@ +package mineplex.game.clans.clans.invsee; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.invsee.commands.InvseeCommand; +import mineplex.game.clans.clans.invsee.ui.InvseeInventory; + +public class InvseeManager extends MiniPlugin +{ + public enum Perm implements Permission + { + INVSEE_COMMAND, + } + + private final Map _viewing = new HashMap<>(); + + public InvseeManager(ClansManager manager) + { + super("Invsee Manager", manager.getPlugin()); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.CMOD.setPermission(Perm.INVSEE_COMMAND, false, true); + PermissionGroup.ADMIN.setPermission(Perm.INVSEE_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new InvseeCommand(this)); + } + + public void doInvsee(OfflinePlayer target, Player requester) + { + InvseeInventory invseeInventory = _viewing.computeIfAbsent(target.getUniqueId(), key -> new InvseeInventory(this, target)); + invseeInventory.addAndShowViewer(requester); + } + + public boolean isBeingInvseen(OfflinePlayer player) + { + return _viewing.containsKey(player.getUniqueId()); + } + + public boolean isInvseeing(Player player) + { + for (InvseeInventory invseeInventory : _viewing.values()) + { + if (invseeInventory.isViewer(player)) + { + return true; + } + } + return false; + } + + public void close(UUID target) + { + InvseeInventory invseeInventory = _viewing.remove(target); + if (invseeInventory == null) + { + log("Expected non-null inventory when closing " + target); + return; + } + UtilServer.Unregister(invseeInventory); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/InvseeModifyOnlineInventoryEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/InvseeModifyOnlineInventoryEvent.java new file mode 100644 index 00000000..bff902bd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/InvseeModifyOnlineInventoryEvent.java @@ -0,0 +1,47 @@ +package mineplex.game.clans.clans.invsee; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class InvseeModifyOnlineInventoryEvent extends Event implements Cancellable +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _modified; + private boolean _cancelled; + + public InvseeModifyOnlineInventoryEvent(Player modified) + { + _modified = modified; + } + + public Player getModified() + { + return _modified; + } + + @Override + public boolean isCancelled() + { + return _cancelled; + } + + @Override + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java new file mode 100644 index 00000000..94002b16 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/commands/InvseeCommand.java @@ -0,0 +1,105 @@ +package mineplex.game.clans.clans.invsee.commands; + +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.MinecraftServer; +import net.minecraft.server.v1_8_R3.NBTTagCompound; +import net.minecraft.server.v1_8_R3.WorldNBTStorage; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.game.clans.clans.invsee.InvseeManager; + +public class InvseeCommand extends CommandBase +{ + public InvseeCommand(InvseeManager plugin) + { + super(plugin, InvseeManager.Perm.INVSEE_COMMAND, "invsee"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0) + { + UtilPlayer.message(caller, F.help("/invsee ", "View a player's inventory", ChatColor.GOLD)); + return; + } + UUID uuid = null; + try + { + uuid = UUID.fromString(args[0]); + } + catch (IllegalArgumentException failed) {} + + OfflinePlayer exactPlayer = Bukkit.getServer().getPlayerExact(args[0]); + if (exactPlayer == null) + { + if (uuid == null) + { + // We don't want to open the wrong OfflinePlayer's inventory, so if we can't fetch the UUID then abort + GameProfile gameProfile = MinecraftServer.getServer().getUserCache().getProfile(args[0]); + if (gameProfile == null) + { + UtilPlayer.message(caller, F.main("Invsee", "Player is offline and we could not find the UUID. Aborting")); + return; + } + uuid = gameProfile.getId(); + } + if (uuid == null) + { + UtilPlayer.message(caller, F.main("Invsee", "Something has gone very wrong. Please report the username/uuid you tried to look up")); + return; + } + // We need to check if we actually have data on this player + // fixme main thread file IO but it's what the server does...? + NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(uuid.toString()); + if (compound == null) + { + UtilPlayer.message(caller, F.main("Invsee", "The player exists, but has never joined this server. No inventory to show")); + return; + } + exactPlayer = Bukkit.getServer().getOfflinePlayer(uuid); + } + if (exactPlayer == null) + { + UtilPlayer.message(caller, F.main("Invsee", "Could not load offline player data. Does the player exist?")); + return; + } + if (exactPlayer.getUniqueId().equals(caller.getUniqueId())) + { + UtilPlayer.message(caller, F.main("Invsee", "You cannot invsee yourself!")); + return; + } + if (Plugin.isBeingInvseen(caller)) + { + UtilPlayer.message(caller, F.main("Invsee", "You cannot use invsee right now. Someone is invseeing you!")); + return; + } + if (exactPlayer.isOnline() && Plugin.isInvseeing((Player) exactPlayer)) + { + UtilPlayer.message(caller, F.main("Invsee", "You cannot use invsee right now. That person is currently using invsee!")); + return; + } + + if (!UtilServer.isTestServer()) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", + new SlackMessage("Clans Command Logger", "crossed_swords", caller.getName() + " has started to invsee " + exactPlayer.getName() + " on " + UtilServer.getServerName() + "."), + true); + } + Plugin.doInvsee(exactPlayer, caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/ui/InvseeInventory.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/ui/InvseeInventory.java new file mode 100644 index 00000000..9fd6e661 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/invsee/ui/InvseeInventory.java @@ -0,0 +1,438 @@ +package mineplex.game.clans.clans.invsee.ui; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.invsee.InvseeManager; +import mineplex.game.clans.clans.invsee.InvseeModifyOnlineInventoryEvent; +import net.minecraft.server.v1_8_R3.ContainerPlayer; +import net.minecraft.server.v1_8_R3.IInventory; +import net.minecraft.server.v1_8_R3.MinecraftServer; +import net.minecraft.server.v1_8_R3.NBTCompressedStreamTools; +import net.minecraft.server.v1_8_R3.NBTTagCompound; +import net.minecraft.server.v1_8_R3.NBTTagList; +import net.minecraft.server.v1_8_R3.PlayerInventory; +import net.minecraft.server.v1_8_R3.WorldNBTStorage; + +public class InvseeInventory implements Listener +{ + private final InvseeManager _invseeManager; + + // This is the UUID of the target player. This should stay constant. Use this for comparison + private final UUID _uuid; + // This is the current player. It will switch when the player joins/quits + private OfflinePlayer _targetPlayer; + // This is the inventory of said player. If the player is not online then this inventory is a fake PlayerInventory + private net.minecraft.server.v1_8_R3.PlayerInventory _playerInventory; + // This is the set of all admins viewing this player + private Set _viewers = new HashSet<>(); + // This is the inventory that all admins will be looking at + private Inventory _inventory; + // This is whether the target player should be allowed to open any inventories + private boolean _canOpenInventory = true; + + public InvseeInventory(InvseeManager manager, OfflinePlayer player) + { + _invseeManager = manager; + _uuid = player.getUniqueId(); + _targetPlayer = player; + + _inventory = UtilServer.getServer().createInventory(null, 6 * 9, player.getName()); + + for (int index = 38; index < 45; index++) + { + _inventory.setItem(index, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.Bold)); + } + _inventory.setItem(47, ItemStackFactory.Instance.CreateStack(Material.STONE_BUTTON, (byte) 0, 1, C.cGreenB + "Inventory Control", generateLore(_canOpenInventory))); + + _inventory.setItem(48, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.Bold)); + + UtilServer.RegisterEvents(this); + updateInventory(); + update(true); + } + + private String[] generateLore(boolean canOpenInventory) + { + return UtilText.splitLinesToArray(new String[]{ + C.cYellow + "Left-Click" + C.cWhite + " to force close any open inventories the target has open", + "", + C.cYellow + "Right-Click" + C.cWhite + " to " + (canOpenInventory ? "disable inventory opening" : "enable inventory opening") + }, LineFormat.LORE); + } + + /* + * Add the player to the list of viewers and open the inventory for him + */ + public void addAndShowViewer(Player requester) + { + _viewers.add(requester); + requester.openInventory(_inventory); + } + + /* + * Check whether the given player is currently viewing this InvseeInventory + */ + public boolean isViewer(Player check) + { + return _viewers.contains(check); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void on(PlayerJoinEvent event) + { + if (_uuid.equals(event.getPlayer().getUniqueId())) + { + _targetPlayer = event.getPlayer(); + updateInventory(); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void on(PlayerQuitEvent event) + { + // If a viewer quit, this will clean it up + _viewers.remove(event.getPlayer()); + if (_viewers.size() == 0) + { + _invseeManager.close(_uuid); + } + else + { + // This should always work + if (_uuid.equals(event.getPlayer().getUniqueId())) + { + _targetPlayer = Bukkit.getOfflinePlayer(_uuid); + updateInventory(); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void on(InventoryOpenEvent event) + { + if (event.getPlayer().getUniqueId().equals(_uuid) && !_canOpenInventory) + { + Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () -> event.getPlayer().closeInventory(), 20); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void on(InventoryCloseEvent event) + { + if (_inventory.equals(event.getInventory())) + { + _viewers.remove(event.getPlayer()); + if (_viewers.size() == 0) + { + _invseeManager.close(_uuid); + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void on(InventoryDragEvent event) + { + if (_inventory.equals(event.getInventory())) + { + ClansManager.getInstance().runSync(() -> + { + update(false); + saveInventory(); + }); + } + else if (event.getWhoClicked().getUniqueId().equals(_targetPlayer.getUniqueId())) + { + ClansManager.getInstance().runSync(() -> + { + update(true); + saveInventory(); + }); + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void on(InventoryClickEvent event) + { + if (_inventory.equals(event.getClickedInventory())) + { + if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.STAINED_GLASS_PANE + && event.getCurrentItem().getItemMeta() != null + && event.getCurrentItem().getItemMeta().getDisplayName() != null + && event.getCurrentItem().getItemMeta().getDisplayName().equals(C.Bold)) + { + event.setCancelled(true); + return; + } + if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.STONE_BUTTON + && event.getCurrentItem().getItemMeta() != null + && event.getCurrentItem().getItemMeta().getDisplayName() != null + && event.getCurrentItem().getItemMeta().getDisplayName().equals(C.cGreenB + "Inventory Control")) + { + event.setCancelled(true); + if (event.getClick() == ClickType.LEFT) + { + if (_targetPlayer.isOnline()) + { + ((Player) _targetPlayer).closeInventory(); + } + } + else if (event.getClick() == ClickType.RIGHT) + { + if (_targetPlayer.isOnline()) + { + _canOpenInventory = !_canOpenInventory; + ItemMeta meta = event.getCurrentItem().getItemMeta(); + meta.setLore(Arrays.asList(generateLore(_canOpenInventory))); + event.getCurrentItem().setItemMeta(meta); + if (!_canOpenInventory) + { + ((Player) _targetPlayer).closeInventory(); + } + } + } + return; + } + + if (MAPPING_INVENTORY_REVERSE.containsKey(event.getRawSlot())) + { + ClansManager.getInstance().runSync(() -> + { + update(false); + saveInventory(); + }); + } + else if (MAPPING_CRAFTING_REVERSE.containsKey(event.getRawSlot())) + { + if (_targetPlayer.isOnline()) + { + ClansManager.getInstance().runSync(() -> + { + update(false); + }); + } + } + else if (event.getRawSlot() == 49) + { + if (_targetPlayer.isOnline()) + { + ClansManager.getInstance().runSync(() -> + { + update(false); + }); + } + } + } + else + { + if (event.getWhoClicked().getUniqueId().equals(_targetPlayer.getUniqueId())) + { + ClansManager.getInstance().runSync(() -> + { + update(true); + }); + } + } + } + + /* + * Updates the inventory instance + */ + private void updateInventory() + { + if (_targetPlayer.isOnline()) + { + _playerInventory = ((CraftPlayer) _targetPlayer).getHandle().inventory; + } + else + { + NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(_uuid.toString()); + // Should not matter if null + _playerInventory = new PlayerInventory(null); + if (compound.hasKeyOfType("Inventory", 9)) + { + _playerInventory.b(compound.getList("Inventory", 10)); + } + } + } + + private void saveInventory() + { + if (!_targetPlayer.isOnline()) + { + try + { + WorldNBTStorage worldNBTStorage = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()); + NBTTagCompound compound = worldNBTStorage.getPlayerData(_uuid.toString()); + compound.set("Inventory", new NBTTagList()); + _playerInventory.a(compound.getList("Inventory", 10)); + File file = new File(worldNBTStorage.getPlayerDir(), _targetPlayer.getUniqueId().toString() + ".dat.tmp"); + File file1 = new File(worldNBTStorage.getPlayerDir(), _targetPlayer.getUniqueId().toString() + ".dat"); + NBTCompressedStreamTools.a(compound, new FileOutputStream(file)); + if (file1.exists()) + { + file1.delete(); + } + + file.renameTo(file1); + } + catch (Exception var5) + { + _invseeManager.log("Failed to save player inventory for " + _targetPlayer.getName()); + for (Player player : _viewers) + { + UtilPlayer.message(player, F.main("Invsee", "Could not save inventory for " + _targetPlayer.getName())); + } + var5.printStackTrace(System.out); + } + } + } + + /** + * Update the player inventory and invsee inventory. + * + * @param targetClick If true, then it means the player being invseen has modified their inventory. Otherwise, it's the admin who has modified something + */ + private void update(boolean targetClick) + { + IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory(); + + if (targetClick) + { + // Update items on hotbar + for (int otherSlot = 0; otherSlot < 9; otherSlot++) + { + iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot)); + } + // Update main inventory + for (int otherSlot = 9; otherSlot < 36; otherSlot++) + { + iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot)); + } + // Update armor + for (int otherSlot = 36; otherSlot < 40; otherSlot++) + { + iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot)); + } + + if (_targetPlayer.isOnline()) + { + ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) _targetPlayer).getHandle().defaultContainer; + for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++) + { + iInventoryThis.setItem(MAPPING_CRAFTING.get(craftingIndex), containerPlayer.craftInventory.getItem(craftingIndex)); + } + } + iInventoryThis.setItem(49, _playerInventory.getCarried()); + } + else + { + if (_targetPlayer.isOnline()) + { + UtilServer.CallEvent(new InvseeModifyOnlineInventoryEvent((Player)_targetPlayer)); + } + + // Update items on hotbar + for (int otherSlot = 0; otherSlot < 9; otherSlot++) + { + _playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot))); + } + // Update main inventory + for (int otherSlot = 9; otherSlot < 36; otherSlot++) + { + _playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot))); + } + // Update armor + for (int otherSlot = 36; otherSlot < 40; otherSlot++) + { + _playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot))); + } + + if (_targetPlayer.isOnline()) + { + ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) _targetPlayer).getHandle().defaultContainer; + for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++) + { + containerPlayer.craftInventory.setItem(craftingIndex, iInventoryThis.getItem(MAPPING_CRAFTING.get(craftingIndex))); + } + } + _playerInventory.setCarried(iInventoryThis.getItem(49)); + } + for (Player viewing : _viewers) + { + viewing.updateInventory(); + } + if (_targetPlayer.isOnline()) + { + ((Player) _targetPlayer).updateInventory(); + } + } + + // Maps slot indices of player inventories to slot indices of double chests + private static final Map MAPPING_INVENTORY = new HashMap<>(); + private static final Map MAPPING_INVENTORY_REVERSE = new HashMap<>(); + // Maps slot indices of player inventories to slot indices of crafting window + private static final Map MAPPING_CRAFTING = new HashMap<>(); + private static final Map MAPPING_CRAFTING_REVERSE = new HashMap<>(); + + static + { + int[] inventoryMapping = new int[] + { + 27, 28, 29, 30, 31, 32, 33, 34, 35, //Hotbar + 0, 1, 2, 3, 4, 5, 6, 7, 8, // Top row inventory + 9, 10, 11, 12, 13, 14, 15, 16, 17, //Second row inventory + 18, 19, 20, 21, 22, 23, 24, 25, 26, //Third row inventory + 53, 52, 51, 50 //Armor + }; + int[] craftingMapping = new int[] + { + 36, 37, //Top crafting + 45, 46 //Bottom crafting + }; + for (int i = 0; i < inventoryMapping.length; i++) + { + MAPPING_INVENTORY.put(i, inventoryMapping[i]); + MAPPING_INVENTORY_REVERSE.put(inventoryMapping[i], i); + } + + for (int i = 0; i < craftingMapping.length; i++) + { + MAPPING_CRAFTING.put(i, craftingMapping[i]); + MAPPING_CRAFTING_REVERSE.put(craftingMapping[i], i); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/CustomItemLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/CustomItemLoot.java new file mode 100644 index 00000000..af16d416 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/CustomItemLoot.java @@ -0,0 +1,83 @@ +package mineplex.game.clans.clans.loot; + +import java.util.Arrays; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilMath; + +public class CustomItemLoot implements ILoot +{ + private Material _material; + private byte _data; + private int _min; + private int _max; + private String _displayName; + private String[] _lore; + + public CustomItemLoot(Material material) + { + this(material, 1, 1); + } + + public CustomItemLoot(Material material, int min, int max) + { + this(material, (byte) 0, min, max, null, new String[] {}); + } + + public CustomItemLoot(Material material, int min, int max, String displayName, String... lore) + { + this(material, (byte) 0, min, max, displayName, lore); + } + + public CustomItemLoot(Material material, byte data, int min, int max, String displayName, String... lore) + { + _material = material; + _data = data; + _min = min; + _max = max; + _displayName = C.Reset + displayName; + _lore = lore; + } + + @Override + public void dropLoot(Location location) + { + location.getWorld().dropItemNaturally(location.clone().add(0, 3, 0), getItemStack()); + } + + @Override + public ItemStack getItemStack() + { + ItemStack stack = new ItemStack(_material, UtilMath.rRange(_min, _max), _data); + + ItemMeta meta = stack.getItemMeta(); + + if (meta == null) + { + meta = Bukkit.getItemFactory().getItemMeta(_material); + } + + if (meta != null && _displayName != null) + { + meta.setDisplayName(_displayName); + } + + if (meta != null && _lore != null && _lore.length > 0) + { + meta.setLore(Arrays.asList(_lore)); + } + + if (meta != null) + { + stack.setItemMeta(meta); + } + + return stack; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GearLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GearLoot.java new file mode 100644 index 00000000..53aa93b1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GearLoot.java @@ -0,0 +1,28 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import mineplex.game.clans.items.GearManager; + +public class GearLoot implements ILoot +{ + private GearManager _gearManager; + + public GearLoot(GearManager gearManager) + { + _gearManager = gearManager; + } + + @Override + public void dropLoot(Location location) + { + _gearManager.spawnItem(location.clone().add(0, 3, 0)); + } + + @Override + public ItemStack getItemStack() + { + return _gearManager.generateItem().toItemStack(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GoldLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GoldLoot.java new file mode 100644 index 00000000..38624951 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GoldLoot.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.economy.GoldManager; + +public class GoldLoot implements ILoot +{ + private GoldManager _goldManager; + private int _min; + private int _max; + + public GoldLoot(GoldManager goldManager, int min, int max) + { + _goldManager = goldManager; + _min = min; + _max = max; + } + + @Override + public void dropLoot(Location location) + { + int count = _min + UtilMath.r(_max - _min); + _goldManager.dropGold(location.clone().add(0, 1, 0), count); + } + + @Override + public ItemStack getItemStack() + { + return null; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GoldTokenLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GoldTokenLoot.java new file mode 100644 index 00000000..1257bb4c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/GoldTokenLoot.java @@ -0,0 +1,40 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.items.economy.GoldToken; + +public class GoldTokenLoot implements ILoot +{ + private int _minGold; + private int _maxGold; + + public GoldTokenLoot(int minGold, int maxGold) + { + _minGold = minGold; + _maxGold = maxGold; + } + + @Override + public void dropLoot(Location location) + { + int gold = _minGold + UtilMath.r(_maxGold - _minGold); + + GoldToken token = new GoldToken(gold); + UtilFirework.playFirework(location.clone().add(0, 3, 0), Type.BALL, Color.YELLOW, true, false); + location.getWorld().dropItemNaturally(location.clone().add(0, 3, 0), token.toItemStack()); + } + + @Override + public ItemStack getItemStack() + { + int gold = _minGold + UtilMath.r(_maxGold - _minGold); + GoldToken token = new GoldToken(gold); + return token.toItemStack(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/ILoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/ILoot.java new file mode 100644 index 00000000..dafd8e0e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/ILoot.java @@ -0,0 +1,12 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +public interface ILoot +{ + public void dropLoot(Location location); + + public ItemStack getItemStack(); + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/ItemLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/ItemLoot.java new file mode 100644 index 00000000..1eaec5ab --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/ItemLoot.java @@ -0,0 +1,45 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilMath; + +public class ItemLoot implements ILoot +{ + private final Material _material; + private final byte _data; + private final int _min, _max; + + public ItemLoot(Material material) + { + this(material, 1, 1); + } + + public ItemLoot(Material material, int min, int max) + { + this(material, (byte) 0, min, max); + } + + public ItemLoot(Material material, byte data, int min, int max) + { + _material = material; + _data = data; + _min = min; + _max = max; + } + + @Override + public void dropLoot(Location location) + { + location.getWorld().dropItemNaturally(location.clone().add(0, 1, 0), getItemStack()); + } + + @Override + public ItemStack getItemStack() + { + int count = UtilMath.rRange(_min, _max); + return new ItemStack(_material, count, (short) 0, _data); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java new file mode 100644 index 00000000..bba6feca --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/LootManager.java @@ -0,0 +1,257 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.weight.WeightSet; +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.items.GearManager; + +public class LootManager +{ + private final GearManager _gearManager; + + private WeightSet _commonSet; + private WeightSet _rareSet; + private WeightSet _bossSet; + private WeightSet _undeadCitySet; + private WeightSet _raidSet; + private WeightSet _capturePointSet; + + public LootManager(GearManager gearManager) + { + _gearManager = gearManager; + + _commonSet = new WeightSet<>(); + _rareSet = new WeightSet<>(); + _bossSet = new WeightSet<>(); + _undeadCitySet = new WeightSet<>(); + _raidSet = new WeightSet<>(); + _capturePointSet = new WeightSet<>(); + + populateCommon(); + populateRare(); + populateBoss(); + populateCity(); + populateRaid(); + populateCapturePoint(); + } + + private void populateCommon() + { + // Food + _commonSet.add(5, new ItemLoot(Material.CARROT, 1, 5)); + _commonSet.add(5, new ItemLoot(Material.APPLE, 1, 3)); + _commonSet.add(5, new ItemLoot(Material.COOKED_BEEF, 1, 3)); + _commonSet.add(5, new ItemLoot(Material.RAW_BEEF, 1, 4)); + _commonSet.add(5, new ItemLoot(Material.POTATO_ITEM, 1, 5)); + + // Armor + _commonSet.add(2, new ItemLoot(Material.IRON_HELMET, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.IRON_CHESTPLATE, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.IRON_LEGGINGS, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.IRON_BOOTS, 1, 1)); + + _commonSet.add(2, new ItemLoot(Material.GOLD_HELMET, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.GOLD_CHESTPLATE, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.GOLD_LEGGINGS, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.GOLD_BOOTS, 1, 1)); + + _commonSet.add(2, new ItemLoot(Material.LEATHER_HELMET, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.LEATHER_CHESTPLATE, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.LEATHER_LEGGINGS, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.LEATHER_BOOTS, 1, 1)); + + _commonSet.add(2, new ItemLoot(Material.DIAMOND_HELMET, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.DIAMOND_CHESTPLATE, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.DIAMOND_LEGGINGS, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.DIAMOND_BOOTS, 1, 1)); + + _commonSet.add(2, new ItemLoot(Material.CHAINMAIL_HELMET, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.CHAINMAIL_CHESTPLATE, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.CHAINMAIL_LEGGINGS, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.CHAINMAIL_BOOTS, 1, 1)); + + _commonSet.add(2, new ItemLoot(Material.IRON_AXE, 1, 1)); + _commonSet.add(2, new ItemLoot(Material.IRON_SWORD, 1, 1)); + + _commonSet.add(2, new CustomItemLoot(Material.STONE_SWORD, 1, 1, "Standard Sword")); + _commonSet.add(2, new CustomItemLoot(Material.STONE_AXE, 1, 1, "Standard Axe")); + _commonSet.add(2, new CustomItemLoot(Material.GOLD_SWORD, 1, 1, "Booster Sword")); + _commonSet.add(2, new CustomItemLoot(Material.GOLD_AXE, 1, 1, "Booster Axe")); + _commonSet.add(2, new CustomItemLoot(Material.DIAMOND_SWORD, 1, 1, "Power Sword")); + _commonSet.add(2, new CustomItemLoot(Material.DIAMOND_AXE, 1, 1, "Power Axe")); + + _commonSet.add(1, new ItemLoot(Material.WOOD_SWORD, 1, 1)); + _commonSet.add(1, new ItemLoot(Material.WOOD_AXE, 1, 1)); + + // Gear + _commonSet.add(1, new GearLoot(_gearManager)); + + // Gold + // _commonSet.add(5, new GoldLoot(_goldManager, 100, 1000)); + _commonSet.add(1, new GoldTokenLoot(5000, 10000)); + } + + private void populateRare() + { + // Gear + _rareSet.add(70, new GearLoot(_gearManager)); + _rareSet.add(10, new GoldTokenLoot(50000, 100000)); + _rareSet.add(20, new MountLoot(1, 3, MountType.values())); + } + + private void populateBoss() + { + _bossSet.add(70, new GearLoot(_gearManager)); + _bossSet.add(10, new GoldTokenLoot(50000, 100000)); + _bossSet.add(20, new MountLoot(1, 3, MountType.values())); + } + + private void populateCity() + { + // Food + _undeadCitySet.add(5, new ItemLoot(Material.CARROT, 1, 5)); + _undeadCitySet.add(5, new ItemLoot(Material.APPLE, 1, 3)); + _undeadCitySet.add(5, new ItemLoot(Material.COOKED_BEEF, 1, 3)); + _undeadCitySet.add(5, new ItemLoot(Material.RAW_BEEF, 1, 4)); + _undeadCitySet.add(5, new ItemLoot(Material.POTATO_ITEM, 1, 5)); + + // Armor + _undeadCitySet.add(3, new ItemLoot(Material.IRON_HELMET, 1, 1)); + _undeadCitySet.add(3, new ItemLoot(Material.IRON_CHESTPLATE, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.IRON_LEGGINGS, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.IRON_BOOTS, 1, 1)); + + _undeadCitySet.add(4, new ItemLoot(Material.GOLD_HELMET, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.GOLD_CHESTPLATE, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.GOLD_LEGGINGS, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.GOLD_BOOTS, 1, 1)); + + _undeadCitySet.add(4, new ItemLoot(Material.LEATHER_HELMET, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.LEATHER_CHESTPLATE, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.LEATHER_LEGGINGS, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.LEATHER_BOOTS, 1, 1)); + + _undeadCitySet.add(4, new ItemLoot(Material.DIAMOND_HELMET, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.DIAMOND_CHESTPLATE, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.DIAMOND_LEGGINGS, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.DIAMOND_BOOTS, 1, 1)); + + _undeadCitySet.add(4, new ItemLoot(Material.CHAINMAIL_HELMET, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.CHAINMAIL_CHESTPLATE, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.CHAINMAIL_LEGGINGS, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.CHAINMAIL_BOOTS, 1, 1)); + + _undeadCitySet.add(4, new ItemLoot(Material.IRON_AXE, 1, 1)); + _undeadCitySet.add(4, new ItemLoot(Material.IRON_SWORD, 1, 1)); + + _undeadCitySet.add(3, new ItemLoot(Material.EMERALD, 10, 15)); + + _undeadCitySet.add(2, new CustomItemLoot(Material.GOLD_SWORD, 1, 1, "Booster Sword")); + _undeadCitySet.add(2, new CustomItemLoot(Material.GOLD_AXE, 1, 1, "Booster Axe")); + _undeadCitySet.add(2, new CustomItemLoot(Material.DIAMOND_SWORD, 1, 1, "Power Sword")); + _undeadCitySet.add(2, new CustomItemLoot(Material.DIAMOND_AXE, 1, 1, "Power Axe")); + + // Gear + _undeadCitySet.add(1, new GearLoot(_gearManager)); + + // Gold + _undeadCitySet.add(1, new GoldTokenLoot(5000, 10000)); + } + + private void populateRaid() + { + _raidSet.add(70, new GearLoot(_gearManager)); + _raidSet.add(10, new GoldTokenLoot(100000, 200000)); + _raidSet.add(20, new MountLoot(2, 3, MountType.values())); + } + + private void populateCapturePoint() + { + // Food + _capturePointSet.add(5, new ItemLoot(Material.CARROT, 32, 32)); + _capturePointSet.add(5, new ItemLoot(Material.APPLE, 32, 32)); + _capturePointSet.add(5, new ItemLoot(Material.COOKED_BEEF, 32, 32)); + _capturePointSet.add(5, new ItemLoot(Material.RAW_BEEF, 32, 32)); + _capturePointSet.add(5, new ItemLoot(Material.POTATO_ITEM, 32, 32)); + + // Armor + _capturePointSet.add(3, new ItemLoot(Material.IRON_HELMET, 1, 1)); + _capturePointSet.add(3, new ItemLoot(Material.IRON_CHESTPLATE, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.IRON_LEGGINGS, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.IRON_BOOTS, 1, 1)); + + _capturePointSet.add(3, new ItemLoot(Material.GOLD_HELMET, 1, 1)); + _capturePointSet.add(3, new ItemLoot(Material.GOLD_CHESTPLATE, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.GOLD_LEGGINGS, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.GOLD_BOOTS, 1, 1)); + + _capturePointSet.add(3, new ItemLoot(Material.LEATHER_HELMET, 1, 1)); + _capturePointSet.add(3, new ItemLoot(Material.LEATHER_CHESTPLATE, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.LEATHER_LEGGINGS, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.LEATHER_BOOTS, 1, 1)); + + _capturePointSet.add(3, new ItemLoot(Material.DIAMOND_HELMET, 1, 1)); + _capturePointSet.add(3, new ItemLoot(Material.DIAMOND_CHESTPLATE, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.DIAMOND_LEGGINGS, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.DIAMOND_BOOTS, 1, 1)); + + _capturePointSet.add(3, new ItemLoot(Material.CHAINMAIL_HELMET, 1, 1)); + _capturePointSet.add(3, new ItemLoot(Material.CHAINMAIL_CHESTPLATE, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.CHAINMAIL_LEGGINGS, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.CHAINMAIL_BOOTS, 1, 1)); + + _capturePointSet.add(4, new ItemLoot(Material.IRON_AXE, 1, 1)); + _capturePointSet.add(4, new ItemLoot(Material.IRON_SWORD, 1, 1)); + + _capturePointSet.add(4, new ItemLoot(Material.EMERALD, 10, 15)); + + _capturePointSet.add(3, new CustomItemLoot(Material.GOLD_SWORD, 1, 1, "Booster Sword")); + _capturePointSet.add(3, new CustomItemLoot(Material.GOLD_AXE, 1, 1, "Booster Axe")); + _capturePointSet.add(3, new CustomItemLoot(Material.DIAMOND_SWORD, 1, 1, "Power Sword")); + _capturePointSet.add(3, new CustomItemLoot(Material.DIAMOND_AXE, 1, 1, "Power Axe")); + + // Gold + _capturePointSet.add(1, new GoldTokenLoot(10000, 50000)); + + // Rune + _capturePointSet.add(2, new RuneLoot()); + } + + public void dropCommon(Location location) + { + _commonSet.generateRandom().dropLoot(location); + } + + public void dropRare(Location location) + { + _rareSet.generateRandom().dropLoot(location); + } + + public void dropBoss(Location location) + { + _bossSet.generateRandom().dropLoot(location); + } + + public void dropUndeadCity(Location location) + { + _undeadCitySet.generateRandom().dropLoot(location); + } + + public void dropRaid(Location location) + { + _raidSet.generateRandom().dropLoot(location); + } + + public void dropCapturePoint(Location location) + { + _capturePointSet.generateRandom().dropLoot(location); + } + + public ItemStack getRareItemStack() + { + return _rareSet.generateRandom().getItemStack(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/MountLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/MountLoot.java new file mode 100644 index 00000000..df326d96 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/MountLoot.java @@ -0,0 +1,45 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.clans.mounts.MountClaimToken; + +public class MountLoot implements ILoot +{ + private int _minStars, _maxStars; + private MountType[] _types; + + public MountLoot(int minStars, int maxStars, MountType... types) + { + _minStars = Math.max(minStars, 1); + _maxStars = Math.min(maxStars, 3); + if (types.length == 0) + { + _types = MountType.values(); + } + else + { + _types = types; + } + } + + @Override + public void dropLoot(Location location) + { + MountClaimToken token = new MountClaimToken(UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.randomElement(_types)); + UtilFirework.playFirework(location.clone().add(0, 3, 0), Type.BALL, Color.SILVER, true, false); + location.getWorld().dropItemNaturally(location.clone().add(0, 3, 0), token.toItem()); + } + + @Override + public ItemStack getItemStack() + { + return new MountClaimToken(UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.rRange(_minStars, _maxStars), UtilMath.randomElement(_types)).toItem(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/RuneLoot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/RuneLoot.java new file mode 100644 index 00000000..542f1c0d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/loot/RuneLoot.java @@ -0,0 +1,44 @@ +package mineplex.game.clans.clans.loot; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; + +public class RuneLoot implements ILoot +{ + private RuneAttribute[] _types; + + public RuneLoot(RuneAttribute... types) + { + if (types.length == 0) + { + _types = RuneAttribute.values(); + } + else + { + _types = types; + } + } + + @Override + public void dropLoot(Location location) + { + RuneAttribute attribute = UtilMath.randomElement(_types); + ItemStack item = ClansManager.getInstance().getGearManager().getRuneManager().getRune(attribute); + UtilFirework.playFirework(location.clone().add(0, 3, 0), Type.BALL, Color.PURPLE, true, false); + location.getWorld().dropItemNaturally(location.clone().add(0, 3, 0), item); + } + + @Override + public ItemStack getItemStack() + { + RuneAttribute attribute = UtilMath.randomElement(_types); + return ClansManager.getInstance().getGearManager().getRuneManager().getRune(attribute); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java new file mode 100644 index 00000000..4dcc784b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java @@ -0,0 +1,989 @@ +package mineplex.game.clans.clans.map; + +import java.io.*; +import java.lang.reflect.Field; +import java.util.*; +import java.util.Map.Entry; + +import mineplex.core.common.util.*; +import mineplex.game.clans.tutorial.TutorialManager; +import net.minecraft.server.v1_8_R3.*; +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.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.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.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.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.game.clans.clans.map.events.PlayerGetMapEvent; +import mineplex.game.clans.clans.worldevent.WorldEventManager; + +/* + * This class manages what the Clans map will show. + * It will scan all relevant chunks (eg players nearby) every ticks + */ +public class ItemMapManager extends MiniPlugin +{ + // Every BLOCK_SCAN_INTERVAL we add as a new region to scan + private static final int BLOCK_SCAN_INTERVAL = 16 * 3; + // 1536 is the width of the entire world from one borderland to the other + private static final int HALF_WORLD_SIZE = 1536 / 2; + // This slot is where the Clans Map will go by default + private static final int CLANS_MAP_SLOT = 8; + + private static final String[] ZOOM_INFO; + + static + { + ZOOM_INFO = new String[4]; + for (int zoomLevel = 0; zoomLevel <= 3; zoomLevel++) + { + StringBuilder progressBar = new StringBuilder(C.cBlue); + + boolean colorChange = false; + for (int i = 2; i >= 0; i--) + { + if (!colorChange && i < zoomLevel) + { + progressBar.append(C.cGray); + colorChange = true; + } + char c; + switch (i) + { + case 0: + c = '█'; + break; + case 1: + c = '▆'; + break; + default: + c = '▄'; + break; + } + for (int a = 0; a < 4; a++) + { + progressBar.append(c); + } + + if (i > 0) + { + progressBar.append(" "); + } + } + ZOOM_INFO[zoomLevel] = progressBar.toString(); + } + } + + private ClansUtility _clansUtility; + private Comparator> _comparator; + private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][]; + private HashMap _map = new HashMap(); + private short _mapId = -1; + private HashMap _mapInfo = new HashMap(); + private HashMap _scale = new HashMap(); + // Use LinkedList because operations are either add(Entry) which is O(1) and remove(0) which is O(1) on LinkedList but O(n) on ArrayList + private LinkedList> _scanList = new LinkedList>(); + private World _world; + private WorldServer _nmsWorld; + private ChunkProviderServer _chunkProviderServer; + private ChunkRegionLoader _chunkRegionLoader; + private WorldEventManager _eventManager; + private TutorialManager _tutorial; + + public ItemMapManager(ClansManager clansManager, TutorialManager tutorial, WorldEventManager eventManager) + { + super("ItemMapManager", clansManager.getPlugin()); + + _clansUtility = clansManager.getClanUtility(); + _eventManager = eventManager; + _tutorial = tutorial; + + _comparator = (o1, o2) -> + { + // 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 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/clans_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 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(this, _eventManager, _tutorial)); + } + + @EventHandler + public void preventMapInItemFrame(PlayerInteractEntityEvent event) + { + if (!(event.getRightClicked() instanceof ItemFrame)) + return; + + if (!isItemClansMap(event.getPlayer().getItemInHand())) + return; + + event.setCancelled(true); + } + + /** + * 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 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); + } + } + + public ClansUtility getClansUtility() + { + return _clansUtility; + } + + 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 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 = event.getAction().name().contains("LEFT"); + + 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 onJoin(PlayerJoinEvent 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); + +// if (UtilInv.getItems(player).isEmpty()) +// { +// 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.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) + { + _scanList.sort(_comparator); + } + + if (_scanList.isEmpty()) + { + return; + } + + Entry entry = _scanList.remove(0); + + int startingX = entry.getKey(); + int startingZ = entry.getValue(); + + boolean outsideMap = startingZ < -HALF_WORLD_SIZE; + + scanWorldMap(startingX, startingZ, !outsideMap, false); + + 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 _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) + { + PlayerGetMapEvent event = UtilServer.CallEvent(new PlayerGetMapEvent(player)); + if (event.isCancelled()) + return; + + for (ItemStack item : UtilInv.getItems(player)) + { + if (isItemClansMap(item)) + { + return; + } + } + + ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle("Clans Map").build(); + + int slot = CLANS_MAP_SLOT; + + ItemStack mapSlot = player.getInventory().getItem(slot); + if (mapSlot != null && mapSlot.getType() != Material.AIR) + { + slot = player.getInventory().firstEmpty(); + } + + 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; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java new file mode 100644 index 00000000..37dfc4dc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java @@ -0,0 +1,358 @@ +package mineplex.game.clans.clans.map; + +import java.awt.*; + +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.common.util.UtilTime; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.tutorial.TutorialManager; + +public class ItemMapRenderer extends MapRenderer +{ + private ItemMapManager _manager; + private TutorialManager _tutorial; + private WorldEventManager _eventManager; + + public ItemMapRenderer(ItemMapManager itemMapManager, WorldEventManager eventManager, TutorialManager tutorial) + { + super(true); + + _manager = itemMapManager; + _tutorial = tutorial; + _eventManager = eventManager; + } + + @Override + public void render(MapView mapView, MapCanvas canvas, Player player) + { +// if (_tutorial.inTutorial(player)) +// { +// renderTutorialMap(mapView, canvas, player); +// } +// else +// { + try + { + renderNormalMap(mapView, canvas, player); + } + catch (Throwable t) + { + System.out.println("Error while rendering map"); + t.printStackTrace(); + } +// } + } + + private void renderTutorialMap(MapView mapView, MapCanvas canvas, Player player) + { + + } + + + private void renderNormalMap(MapView mapView, MapCanvas canvas, Player player) + { + MapInfo info = _manager.getMap(player); + + if (info == null) + { + return; + } + + int scale = info.getScale(); + int zoom = _manager.getZoom(scale); + + ClanInfo clan = _manager.getClansUtility().getClanByPlayer(player); + + Byte[][] map = _manager.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(), 4000)) + { + 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; + + ClaimLocation chunk = ClaimLocation.of("world", (int) Math.floor(blockX / 16D), (int) Math.floor(blockZ / 16D)); + + ClanInfo owningClan = _manager.getClansUtility().getOwner(chunk); + + if (owningClan != null) + { + boolean colorAll = scale > 0; + Color clanColor = null; + Color clanColor2 = null; + + if (owningClan == clan) + { + clanColor = Color.CYAN; + } + else + { + ClansUtility.ClanRelation relation = _manager.getClansUtility().rel(clan, owningClan); + + if (owningClan.isAdmin()) + { + colorAll = false; + + if (owningClan.getName().equals("Shops")) + { + clanColor = Color.WHITE; + clanColor2 = new Color(50, 150, 255); + + if (_manager.getClansUtility().relPT(player, chunk) == ClansUtility.ClanRelation.SAFE) + clanColor2 = new Color(50, 150, 255); + } + else if (owningClan.getName().equals("Spawn")) + { + clanColor = Color.WHITE; + clanColor2 = new Color(0, 255, 100); + } + else if (owningClan.getName().equals("Fields")) + { + clanColor = Color.WHITE; + clanColor2 = new Color(255, 120, 0); + } + else + { + clanColor = Color.WHITE; + clanColor2 = Color.GRAY; + } + } + else if (relation == ClansUtility.ClanRelation.WAR_LOSING) + { + clanColor = Color.RED; + } + else if (relation == ClansUtility.ClanRelation.WAR_WINNING) + { + clanColor = Color.MAGENTA; + } + else if (relation == ClansUtility.ClanRelation.ALLY || relation == ClansUtility.ClanRelation.ALLY_TRUST) + { + clanColor = Color.GREEN; + } + else if (relation == ClansUtility.ClanRelation.SELF) + { + clanColor = Color.CYAN; + } + else + { + // Neutral + clanColor = Color.YELLOW; + } + } + + if (clanColor != 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; + int chunkX1 = (int) Math.floor(blockX / 16D); + int chunkZ1 = (int) Math.floor(blockZ / 16D); + + //Border + if (colorAll || + + ((chunkBX == 0 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner(ClaimLocation.of("world", chunkX1 - 1, chunkZ1))) + + || ((chunkBZ == 0 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner(ClaimLocation.of("world", chunkX1, chunkZ1 - 1))) + + || ((chunkBX + zoom > 15 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner(ClaimLocation.of("world", chunkX1 + 1, chunkZ1))) + + || ((chunkBZ + zoom > 15 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner(ClaimLocation.of("world", chunkX1, chunkZ1 + 1)))) + { + Color cColor = MapPalette.getColor(color); + double clans = colorAll ? 1 : 0.8;// 0.65; + + //Use clanColor2 no matter what for admins + Color drawColor = clanColor; + if (owningClan.isAdmin() && clanColor2 != null) + { + drawColor = clanColor2; + clans = 1; + } + + double base = 1 - clans; + + int r = (int) ((cColor.getRed() * base) + (drawColor.getRed() * clans)); + int b = (int) ((cColor.getBlue() * base) + (drawColor.getBlue() * clans)); + int g = (int) ((cColor.getGreen() * base) + (drawColor.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; + Color drawColor = clanColor; + if (checker && owningClan.isAdmin() && clanColor2 != null) + { + drawColor = clanColor2; + clans = 1; + } + + double base = 1 - clans; + + int r = (int) ((cColor.getRed() * base) + (drawColor.getRed() * clans)); + int b = (int) ((cColor.getBlue() * base) + (drawColor.getBlue() * clans)); + int g = (int) ((cColor.getGreen() * base) + (drawColor.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 : _eventManager.getEvents()) + { + if (event.getState() != EventState.LIVE) + continue; + + Location point = event.getCenterLocation(); + 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); + } + } + + 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) + { + ClanInfo otherClan = _manager.getClansUtility().getClanByPlayer(other); + + MapCursor.Type cursorDisplay; + + if (player == other) + { + cursorDisplay = MapCursor.Type.WHITE_POINTER; + } + else if (otherClan == null || clan == null) + { + continue; + } + else if (otherClan == clan) + { + cursorDisplay = MapCursor.Type.BLUE_POINTER; + } + else if (otherClan.isAlly(clan.getName())) + { + cursorDisplay = MapCursor.Type.GREEN_POINTER; + } + else + { + 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); + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/MapInfo.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/MapInfo.java new file mode 100644 index 00000000..ef79024f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/MapInfo.java @@ -0,0 +1,124 @@ +package mineplex.game.clans.clans.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 _lastZooms = new ArrayList(); + 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 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; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java new file mode 100644 index 00000000..e13645b8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/events/PlayerGetMapEvent.java @@ -0,0 +1,47 @@ +package mineplex.game.clans.clans.map.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/* + * This event is called when a Player is about to receive a Clans Map + */ +public class PlayerGetMapEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + + private boolean _cancelled; + + public PlayerGetMapEvent(Player player) + { + _player = player; + } + + public Player getPlayer() + { + return _player; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/AltManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/AltManager.java new file mode 100644 index 00000000..143a2b1a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/AltManager.java @@ -0,0 +1,495 @@ +package mineplex.game.clans.clans.moderation.antialt; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +import org.apache.commons.lang3.tuple.Triple; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; +import org.bukkit.event.player.PlayerJoinEvent; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.command.CommandBase; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.punish.clans.ClansBanManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.moderation.antialt.AltRepository.ChainedDatabaseAction; +import mineplex.game.clans.clans.moderation.antialt.AltRepository.IpUnbanResult; +import mineplex.game.clans.clans.moderation.antialt.AltRepository.IpUnwhitelistResult; +import mineplex.game.clans.clans.moderation.antialt.IpAPIData.ImmutableIpAPIData; +import mineplex.serverdata.Utility; +import mineplex.serverdata.commands.ServerCommandManager; +import net.md_5.bungee.api.ChatColor; + +public class AltManager extends MiniPlugin +{ + public enum Perm implements Permission + { + BAN_IP, + UNBAN_IP, + WHITELIST_IP, + UNWHITELIST_IP, + CHECK_IP, + ACCOUNT_HISTORY, + IP_HISTORY, + CHECK_ALTS, + BYPASS_ALT_CHECK, + } + + private final ClansBanManager _punish = Managers.require(ClansBanManager.class); + private final CoreClientManager _clientManager = Managers.require(CoreClientManager.class); + protected final AltRepository _repo; + private final int _serverId; + private final Map> _vpnCache = new HashMap<>(); + + public AltManager() + { + super("Alt Manager"); + + _serverId = ClansManager.getInstance().getServerId(); + _repo = new AltRepository(); + + addCommand(new CommandBase(this, Perm.BAN_IP, "banip") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /banip ")); + return; + } + final String ip = args[0]; + _repo.banIp(ip, caller.getName(), success -> + { + if (success) + { + UtilPlayer.message(caller, F.main(getName(), "Ip successfully banned!")); + new IpBanNotification(ip).publish(); + } + else + { + UtilPlayer.message(caller, F.main(getName(), "An error occurred while attempting to ban that ip!")); + } + }); + } + }); + addCommand(new CommandBase(this, Perm.UNBAN_IP, "unbanip") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /unbanip ")); + return; + } + final String ip = args[0]; + _repo.unbanIp(ip, result -> + { + if (result == IpUnbanResult.UNBANNED) + { + UtilPlayer.message(caller, F.main(getName(), "Ip successfully unbanned!")); + } + else if (result == IpUnbanResult.NOT_BANNED) + { + UtilPlayer.message(caller, F.main(getName(), "That ip was not banned!")); + } + else + { + UtilPlayer.message(caller, F.main(getName(), "An error occurred while attempting to unban that ip!")); + } + }); + } + }); + addCommand(new CommandBase(this, Perm.WHITELIST_IP, "whitelistip") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /whitelistip ")); + return; + } + final String ip = args[0]; + final int additionalAccounts; + try + { + additionalAccounts = Integer.parseInt(args[1]); + } + catch (NumberFormatException ex) + { + UtilPlayer.message(caller, F.main(getName(), "That is not a valid number of additional accounts!")); + return; + } + _repo.whitelistIp(ip, caller.getName(), additionalAccounts, success -> + { + if (success) + { + UtilPlayer.message(caller, F.main(getName(), "Ip successfully whitelisted!")); + } + else + { + UtilPlayer.message(caller, F.main(getName(), "An error occurred while attempting to whitelist that ip!")); + } + }); + } + }); + addCommand(new CommandBase(this, Perm.UNWHITELIST_IP, "unwhitelistip") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /unwhitelistip ")); + return; + } + final String ip = args[0]; + _repo.unwhitelistIp(ip, result -> + { + if (result == IpUnwhitelistResult.UNWHITELISTED) + { + UtilPlayer.message(caller, F.main(getName(), "Ip successfully unwhitelisted!")); + } + else if (result == IpUnwhitelistResult.NOT_WHITELISTED) + { + UtilPlayer.message(caller, F.main(getName(), "That ip was not whitelisted!")); + } + else + { + UtilPlayer.message(caller, F.main(getName(), "An error occurred while attempting to unwhitelist that ip!")); + } + }); + } + }); + addCommand(new CommandBase(this, Perm.CHECK_IP, "checkip") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /checkip ")); + return; + } + final String ip = args[0]; + runAsync(() -> + { + Triple status = checkIpStatus(ip); + final boolean banned = status.getLeft(); + final boolean whitelisted = status.getMiddle(); + final int additionalAccounts = status.getRight(); + runSync(() -> + { + if (banned) + { + UtilPlayer.message(caller, F.main(getName(), "That ip is banned!")); + } + else + { + UtilPlayer.message(caller, F.main(getName(), "That ip is not banned!")); + } + if (whitelisted) + { + UtilPlayer.message(caller, F.main(getName(), "That ip is whitelisted with " + F.elem(String.valueOf(additionalAccounts)) + " additional accounts!")); + } + else + { + UtilPlayer.message(caller, F.main(getName(), "That ip is not whitelisted!")); + } + }); + }); + } + }); + addCommand(new CommandBase(this, Perm.ACCOUNT_HISTORY, "accounthistory") + { + @SuppressWarnings("deprecation") + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /accounthistory ")); + return; + } + final String ip = args[0]; + if (Boolean.valueOf(args[1])) + { + _repo.loadAccounts(ip, _serverId, accounts -> + { + UtilPlayer.message(caller, F.main(getName(), "Accounts logged in under that ip on this server:")); + for (String name : accounts) + { + Player player = Bukkit.getPlayer(name); + ChatColor cc = ChatColor.GRAY; + if (player != null) + { + cc = ChatColor.GREEN; + } + UtilPlayer.message(caller, C.cBlue + "- " + cc + name); + } + }); + } + else + { + _repo.loadAccounts(ip, accounts -> + { + UtilPlayer.message(caller, F.main(getName(), "Accounts logged in under that ip:")); + for (String name : accounts) + { + OfflinePlayer op = Bukkit.getOfflinePlayer(name); + ChatColor cc = ChatColor.GRAY; + if (op.hasPlayedBefore()) + { + cc = ChatColor.RED; + } + if (op.isOnline()) + { + cc = ChatColor.GREEN; + } + UtilPlayer.message(caller, C.cBlue + "- " + cc + name); + } + }); + } + } + }); + addCommand(new CommandBase(this, Perm.IP_HISTORY, "iphistory") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /iphistory ")); + return; + } + final String name = args[0]; + final boolean local = Boolean.valueOf(args[1]); + _clientManager.loadClientByName(name, client -> + { + if (client == null) + { + UtilPlayer.message(caller, F.main(getName(), "That player was not found!")); + } + else + { + final int accountId = client.getAccountId(); + if (local) + { + _repo.loadIps(accountId, _serverId, ips -> + { + UtilPlayer.message(caller, F.main(getName(), "Ips used by " + F.elem(client.getName()) + " on this server:")); + for (String ip : ips) + { + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + ip); + } + }); + } + else + { + _repo.loadIps(accountId, ips -> + { + UtilPlayer.message(caller, F.main(getName(), "Ips used by " + F.elem(client.getName()) + ":")); + for (String ip : ips) + { + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + ip); + } + }); + } + } + }); + } + }); + addCommand(new CommandBase(this, Perm.CHECK_ALTS, "alts") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /alts ")); + return; + } + final String name = args[0]; + _clientManager.loadClientByName(name, client -> + { + if (client == null) + { + UtilPlayer.message(caller, F.main(getName(), "That player was not found!")); + } + else + { + final int accountId = client.getAccountId(); + _repo.loadDuplicateAccounts(accountId, accounts -> + { + UtilPlayer.message(caller, F.main(getName(), "Accounts sharing an ip with " + F.elem(client.getName()) + ":")); + for (String account : accounts) + { + if (account.equals(client.getName())) + { + continue; + } + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + account); + } + }); + } + }); + } + }); + ServerCommandManager.getInstance().registerCommandType(IpBanNotification.class, notification -> + { + runSync(() -> + { + Bukkit.getOnlinePlayers().forEach(player -> + { + if (player.getAddress().getAddress().toString().substring(1).equals(notification.getIp())) + { + player.kickPlayer(C.cRedB + "Your IP has been suspended from Mineplex Clans.\n" + C.cGold + "Visit http://www.mineplex.com/appeals to appeal this ban."); + } + }); + }); + }); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.BAN_IP, true, true); + PermissionGroup.ADMIN.setPermission(Perm.UNBAN_IP, true, true); + PermissionGroup.ADMIN.setPermission(Perm.WHITELIST_IP, true, true); + PermissionGroup.ADMIN.setPermission(Perm.UNWHITELIST_IP, true, true); + PermissionGroup.ADMIN.setPermission(Perm.CHECK_IP, true, true); + PermissionGroup.ADMIN.setPermission(Perm.ACCOUNT_HISTORY, true, true); + PermissionGroup.ADMIN.setPermission(Perm.IP_HISTORY, true, true); + PermissionGroup.ADMIN.setPermission(Perm.CHECK_ALTS, true, true); + PermissionGroup.CMOD.setPermission(Perm.CHECK_ALTS, false, true); + } + + private synchronized boolean checkForVPN(String ipAddress) + { + _vpnCache.entrySet().removeIf(entry -> UtilTime.elapsed(entry.getValue().getRight(), 120000)); //expire cache + Pair cacheValue = _vpnCache.computeIfAbsent(ipAddress, ip -> + { + try + { + StringBuilder response = new StringBuilder(); + URLConnection connection = new URL("http://api.vpnblocker.net/v2/json/" + ipAddress + "/1YimOXUxTgh34kNRZYF31y5YEw8Phs").openConnection(); + connection.setConnectTimeout(10000); + connection.setRequestProperty("User-Agent", "Mineplex Clans"); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) + { + reader.lines().forEachOrdered(response::append); + } + if (response.length() == 0) + { + return Pair.create(new IpAPIData().makeImmutable(), System.currentTimeMillis()); + } + IpAPIData data = Utility.deserialize(response.toString(), IpAPIData.class); + if (data == null) + { + return Pair.create(new IpAPIData().makeImmutable(), System.currentTimeMillis()); + } + return Pair.create(data.makeImmutable(), System.currentTimeMillis()); + } + catch (IOException e) + { + e.printStackTrace(); + return Pair.create(new IpAPIData().makeImmutable(), System.currentTimeMillis()); + } + }); + if (cacheValue.getLeft().host_ip) + { + return true; + } + return false; + } + + private Triple checkIpStatus(String ipAddress) + { + ChainedDatabaseAction action = _repo.checkIpBanned(ipAddress).chain(_repo.checkIpWhitelisted(ipAddress)); + action.execute(); + return Triple.of(action.getResult(AltRepository.BAN_STATUS_KEY), action.getResult(AltRepository.WHITELIST_STATUS_KEY), action.getResult(AltRepository.WHITELIST_ADDITIONAL_ACCOUNTS_KEY)); + } + + private void storeLogin(int accountId, String ipAddress) + { + _repo.login(ipAddress, accountId, _serverId).executeAsync(null); + } + + private void checkAltAndStore(int accountId, String ipAddress, Consumer callback) + { + ChainedDatabaseAction action = _repo.checkAltAccount(ipAddress, _serverId, accountId).chain(_repo.checkIpWhitelisted(ipAddress)).chain(_repo.login(ipAddress, accountId, _serverId)); + action.executeAsync(() -> + { + int alts = action.getResult(AltRepository.ALT_COUNT_KEY); + boolean isWhitelisted = action.getResult(AltRepository.WHITELIST_STATUS_KEY); + int additionalAccounts = action.getResult(AltRepository.WHITELIST_ADDITIONAL_ACCOUNTS_KEY); + callback.accept(alts > additionalAccounts && !isWhitelisted); + }); + } + +// @EventHandler(priority = EventPriority.HIGH) + public void onLogin(AsyncPlayerPreLoginEvent event) + { + if (event.getLoginResult() != Result.ALLOWED) + { + return; + } + + final String ipAddress = event.getAddress().toString().substring(1); + Triple status = checkIpStatus(ipAddress); + if (!status.getMiddle() && checkForVPN(ipAddress)) + { + event.disallow(Result.KICK_BANNED, C.cRedB + "VPN/Proxy usage is not permitted on Mineplex Clans"); + return; + } + if (status.getLeft()) + { + event.disallow(Result.KICK_BANNED, C.cRedB + "Your IP has been suspended from Mineplex Clans.\n" + C.cGold + "Visit http://www.mineplex.com/appeals to appeal this ban."); + return; + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + /*if (_clientManager.Get(player).hasPermission(Perm.BYPASS_ALT_CHECK)) + { + return; + }*/ + final int accountId = _clientManager.getAccountId(player); + final String ipAddress = player.getAddress().getAddress().toString().substring(1); + + /*checkAltAndStore(accountId, ipAddress, alt -> + { + if (alt) + { + player.kickPlayer(C.cRed + "You have been disconnected for Unauthorized Alting!"); + } + });*/ + storeLogin(accountId, ipAddress); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/AltRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/AltRepository.java new file mode 100644 index 00000000..75367e7f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/AltRepository.java @@ -0,0 +1,435 @@ +package mineplex.game.clans.clans.moderation.antialt; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import mineplex.core.Managers; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.common.util.UtilServer; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class AltRepository extends RepositoryBase +{ + public static final String ALT_COUNT_KEY = "ALT_ACCOUNTS"; + public static final String WHITELIST_STATUS_KEY = "WHITELISTED_IP"; + public static final String WHITELIST_ADDITIONAL_ACCOUNTS_KEY = "WHITELISTED_ADDITIONAL_ACCOUNTS"; + public static final String BAN_STATUS_KEY = "BANNED_IP"; + + private static final String CREATE_IP_BAN_TABLE = "CREATE TABLE IF NOT EXISTS clansIpBans (ipAddress VARCHAR(16), admin VARCHAR(40), PRIMARY KEY (ipAddress), INDEX adminIndex (admin));"; + private static final String FETCH_IP_BAN_INFO = "SELECT * FROM clansIpBans WHERE ipAddress=?;"; + private static final String BAN_IP = "INSERT INTO clansIpBans (ipAddress, admin) VALUES (?, ?) ON DUPLICATE KEY UPDATE admin=VALUES(admin);"; + private static final String UNBAN_IP = "DELETE FROM clansIpBans WHERE ipAddress=?;"; + + private static final String CREATE_IP_WHITELIST_TABLE = "CREATE TABLE IF NOT EXISTS clansIpWhitelists (ipAddress VARCHAR(16), admin VARCHAR(40), additionalAccounts INT, PRIMARY KEY (ipAddress), INDEX adminIndex (admin));"; + private static final String FETCH_IP_WHITELIST_INFO = "SELECT * FROM clansIpWhitelists WHERE ipAddress=?;"; + private static final String WHITELIST_IP = "INSERT INTO clansIpWhitelists (ipAddress, admin, additionalAccounts) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE admin=VALUES(admin), additionalAccounts=VALUES(additionalAccounts);"; + private static final String UNWHITELIST_IP = "DELETE FROM clansIpWhitelists WHERE ipAddress=?;"; + + private static final String CREATE_IP_HISTORY_TABLE = "CREATE TABLE IF NOT EXISTS clansIpHistory (ipAddress VARCHAR(16), accountId INT, serverId INT, PRIMARY KEY (ipAddress, accountId, serverId), INDEX ipIndex (ipAddress), INDEX accountIndex (accountId), INDEX accountServerIndex (accountId, serverId), INDEX ipServerIndex (ipAddress, serverId), FOREIGN KEY (serverId) REFERENCES clanServer(id), FOREIGN KEY (accountId) REFERENCES accounts(id));"; + private static final String FETCH_LOCAL_ACCOUNT_IPS = "SELECT ipAddress FROM clansIpHistory WHERE accountId=? AND serverId=?;"; + private static final String FETCH_ACCOUNT_IPS = "SELECT DISTINCT ipAddress FROM clansIpHistory WHERE accountId=?;"; + private static final String FETCH_IP_ACCOUNTS = "SELECT DISTINCT name FROM accounts WHERE id IN (SELECT accountId FROM clansIpHistory WHERE ipAddress=?);"; + private static final String FETCH_LOCAL_IP_ACCOUNTS = "SELECT DISTINCT name FROM accounts WHERE id IN (SELECT accountId FROM clansIpHistory WHERE ipAddress=? AND serverId=?);"; + private static final String FETCH_LOCAL_IP_ACCOUNT_IDS = "SELECT DISTINCT accountId FROM clansIpHistory WHERE ipAddress=? AND serverId=?;"; + private static final String FETCH_DUPLICATE_ACCOUNTS = "SELECT DISTINCT name FROM accounts WHERE id IN (SELECT DISTINCT accountId FROM clansIpHistory WHERE ipAddress IN (SELECT DISTINCT ipAddress FROM clansIpHistory WHERE accountId=?));"; + private static final String LOGIN_ACCOUNT = "INSERT INTO clansIpHistory (ipAddress, accountId, serverId) VALUES (?, ?, ?);"; + + public AltRepository() + { + super(DBPool.getAccount()); + } + + public ChainedDatabaseAction checkIpBanned(String ipAddress) + { + return new ChainedDatabaseAction((connection, resultMap) -> + { + EnclosedObject recordExists = new EnclosedObject<>(false); + + executeQuery(connection, FETCH_IP_BAN_INFO, resultSet -> + { + recordExists.Set(resultSet.next()); + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress)); + + resultMap.put(BAN_STATUS_KEY, recordExists.Get()); + }); + } + + public ChainedDatabaseAction checkIpWhitelisted(String ipAddress) + { + return new ChainedDatabaseAction((connection, resultMap) -> + { + EnclosedObject recordExists = new EnclosedObject<>(false); + EnclosedObject additionalAccounts = new EnclosedObject<>(0); + + executeQuery(connection, FETCH_IP_WHITELIST_INFO, resultSet -> + { + recordExists.Set(resultSet.next()); + if (recordExists.Get()) + { + additionalAccounts.Set(resultSet.getInt("additionalAccounts")); + } + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress)); + + resultMap.put(WHITELIST_STATUS_KEY, recordExists.Get()); + resultMap.put(WHITELIST_ADDITIONAL_ACCOUNTS_KEY, additionalAccounts.Get()); + }); + } + + public ChainedDatabaseAction login(String ipAddress, int accountId, int serverId) + { + return new ChainedDatabaseAction((connection, resultMap) -> + { + List accounts = new ArrayList<>(); + executeQuery(connection, FETCH_LOCAL_IP_ACCOUNT_IDS, rs -> + { + while (rs.next()) + { + accounts.add(rs.getInt(1)); + } + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress), new ColumnInt("serverId", serverId)); + + if (!accounts.contains(accountId)) + { + executeInsert(connection, LOGIN_ACCOUNT, null, null, new ColumnVarChar(ipAddress, ipAddress.length(), ipAddress), new ColumnInt("accountId", accountId), new ColumnInt("serverId", serverId)); + } + }); + } + + public ChainedDatabaseAction checkAltAccount(String ipAddress, int serverId, Integer... accountIgnore) + { + return new ChainedDatabaseAction((connection, resultMap) -> + { + List accounts = new ArrayList<>(); + List ignore = Arrays.asList(accountIgnore); + executeQuery(connection, FETCH_LOCAL_IP_ACCOUNT_IDS, rs -> + { + while (rs.next()) + { + if (!ignore.contains(rs.getInt(1))) + { + accounts.add(rs.getInt(1)); + } + } + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress), new ColumnInt("serverId", serverId)); + + resultMap.put(ALT_COUNT_KEY, accounts.size()); + }); + } + + public void banIp(String ipAddress, String admin, Consumer callback) + { + UtilServer.runAsync(() -> + { + Consumer passThrough = success -> + { + if (callback != null) + { + UtilServer.runSync(() -> callback.accept(success)); + } + }; + executeInsert(BAN_IP, rs -> passThrough.accept(true), () -> passThrough.accept(false), new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress), new ColumnVarChar("admin", admin.length(), admin)); + }); + } + + public void unbanIp(String ipAddress, Consumer callback) + { + UtilServer.runAsync(() -> + { + Consumer passThrough = result -> + { + if (callback != null) + { + UtilServer.runSync(() -> callback.accept(result)); + } + }; + EnclosedObject errored = new EnclosedObject<>(false); + + int rows = executeUpdate(UNBAN_IP, () -> + { + errored.Set(true); + passThrough.accept(IpUnbanResult.ERROR); + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress)); + + if (!errored.Get()) + { + if (rows > 0) + { + passThrough.accept(IpUnbanResult.UNBANNED); + } + else + { + passThrough.accept(IpUnbanResult.NOT_BANNED); + } + } + }); + } + + public void whitelistIp(String ipAddress, String admin, int additionalAccounts, Consumer callback) + { + UtilServer.runAsync(() -> + { + Consumer passThrough = success -> + { + if (callback != null) + { + UtilServer.runSync(() -> callback.accept(success)); + } + }; + executeInsert(WHITELIST_IP, rs -> passThrough.accept(true), () -> passThrough.accept(false), new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress), new ColumnVarChar("admin", admin.length(), admin), new ColumnInt("additionalAccounts", additionalAccounts)); + }); + } + + public void unwhitelistIp(String ipAddress, Consumer callback) + { + UtilServer.runAsync(() -> + { + Consumer passThrough = result -> + { + if (callback != null) + { + UtilServer.runSync(() -> callback.accept(result)); + } + }; + EnclosedObject errored = new EnclosedObject<>(false); + + int rows = executeUpdate(UNWHITELIST_IP, () -> + { + errored.Set(true); + passThrough.accept(IpUnwhitelistResult.ERROR); + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress)); + + if (!errored.Get()) + { + if (rows > 0) + { + passThrough.accept(IpUnwhitelistResult.UNWHITELISTED); + } + else + { + passThrough.accept(IpUnwhitelistResult.NOT_WHITELISTED); + } + } + }); + } + + public void loadAccounts(String ipAddress, Consumer> accountCallback) + { + UtilServer.runAsync(() -> + { + List accounts = new ArrayList<>(); + executeQuery(FETCH_IP_ACCOUNTS, rs -> + { + while (rs.next()) + { + accounts.add(rs.getString(1)); + } + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress)); + + UtilServer.runSync(() -> + { + accountCallback.accept(accounts); + }); + }); + } + + public void loadAccountIds(String ipAddress, int serverId, Consumer> accountCallback) + { + UtilServer.runAsync(() -> + { + List accounts = new ArrayList<>(); + executeQuery(FETCH_LOCAL_IP_ACCOUNT_IDS, rs -> + { + while (rs.next()) + { + accounts.add(rs.getInt(1)); + } + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress), new ColumnInt("serverId", serverId)); + + UtilServer.runSync(() -> + { + accountCallback.accept(accounts); + }); + }); + } + + public void loadAccounts(String ipAddress, int serverId, Consumer> accountCallback) + { + UtilServer.runAsync(() -> + { + List accounts = new ArrayList<>(); + executeQuery(FETCH_LOCAL_IP_ACCOUNTS, rs -> + { + while (rs.next()) + { + accounts.add(rs.getString(1)); + } + }, new ColumnVarChar("ipAddress", ipAddress.length(), ipAddress), new ColumnInt("serverId", serverId)); + + UtilServer.runSync(() -> + { + accountCallback.accept(accounts); + }); + }); + } + + public void loadIps(int accountId, Consumer> ipCallback) + { + UtilServer.runAsync(() -> + { + List ips = new ArrayList<>(); + executeQuery(FETCH_ACCOUNT_IPS, rs -> + { + while (rs.next()) + { + ips.add(rs.getString(1)); + } + }, new ColumnInt("accountId", accountId)); + + UtilServer.runSync(() -> + { + ipCallback.accept(ips); + }); + }); + } + + public void loadIps(int accountId, int serverId, Consumer> ipCallback) + { + UtilServer.runAsync(() -> + { + List ips = new ArrayList<>(); + executeQuery(FETCH_LOCAL_ACCOUNT_IPS, rs -> + { + while (rs.next()) + { + ips.add(rs.getString(1)); + } + }, new ColumnInt("accountId", accountId), new ColumnInt("serverId", serverId)); + + UtilServer.runSync(() -> + { + ipCallback.accept(ips); + }); + }); + } + + public void loadDuplicateAccounts(int accountId, Consumer> nameCallback) + { + UtilServer.runAsync(() -> + { + List accounts = new ArrayList<>(); + executeQuery(FETCH_DUPLICATE_ACCOUNTS, rs -> + { + while (rs.next()) + { + accounts.add(rs.getString(1)); + } + }, new ColumnVarChar("accountId", accountId)); + + UtilServer.runSync(() -> + { + nameCallback.accept(accounts); + }); + }); + } + + protected static enum IpUnbanResult + { + UNBANNED, + NOT_BANNED, + ERROR; + } + + protected static enum IpUnwhitelistResult + { + UNWHITELISTED, + NOT_WHITELISTED, + ERROR; + } + + protected static class ChainedDatabaseAction + { + private final BiConsumer> _action; + private final Map _results = new HashMap<>(); + private final Object _resultLock = new Object(); + + public ChainedDatabaseAction(BiConsumer> action) + { + _action = action; + } + + public ChainedDatabaseAction chain(ChainedDatabaseAction action) + { + return new ChainedDatabaseAction(_action.andThen(action._action)); + } + + @SuppressWarnings("unchecked") + public T getResult(String key) + { + synchronized (_resultLock) + { + Object result = _results.get(key); + if (result == null) + { + return null; + } + try + { + return (T) result; + } + catch (ClassCastException ex) + { + ex.printStackTrace(); + return null; + } + } + } + + public void execute() + { + synchronized (_resultLock) + { + try (Connection c = Managers.get(AltManager.class)._repo.getConnection()) + { + _action.accept(c, _results); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + public void executeAsync(Runnable onComplete) + { + UtilServer.runAsync(() -> + { + synchronized (_resultLock) + { + try (Connection c = Managers.get(AltManager.class)._repo.getConnection()) + { + _action.accept(c, _results); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + if (onComplete == null) + { + return; + } + UtilServer.runSync(onComplete); + }); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/IpAPIData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/IpAPIData.java new file mode 100644 index 00000000..6f7ec852 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/IpAPIData.java @@ -0,0 +1,155 @@ +package mineplex.game.clans.clans.moderation.antialt; + +import com.google.gson.annotations.SerializedName; + +public class IpAPIData +{ + public String status; + + public String msg; + + @SerializedName("package") + public String accessPackage; + + public int remaining_requests; + + public String ipaddress; + + @SerializedName("host-ip") + public boolean host_ip; + + public String org; + + public RegionInfo country; + + public RegionInfo subdivision; + + public String city; + + public String postal; + + public LocationInfo location; + + public ImmutableIpAPIData makeImmutable() + { + return ImmutableIpAPIData.create(this); + } + + public static class ImmutableIpAPIData + { + public final String status; + + public final String msg; + + @SerializedName("package") + public final String accessPackage; + + public final int remaining_requests; + + public final String ipaddress; + + @SerializedName("host-ip") + public final boolean host_ip; + + public final String org; + + public final ImmutableRegionInfo country; + + public final ImmutableRegionInfo subdivision; + + public final String city; + + public final String postal; + + public final ImmutableLocationInfo location; + + private ImmutableIpAPIData(IpAPIData base) + { + status = base.status; + msg = base.msg; + accessPackage = base.accessPackage; + remaining_requests = base.remaining_requests; + ipaddress = base.ipaddress; + host_ip = base.host_ip; + org = base.org; + country = ImmutableRegionInfo.create(base.country); + subdivision = ImmutableRegionInfo.create(base.subdivision); + city = base.city; + postal = base.postal; + location = ImmutableLocationInfo.create(base.location); + } + + public static ImmutableIpAPIData create(IpAPIData base) + { + if (base == null) + { + return null; + } + return new ImmutableIpAPIData(base); + } + } + + public static class RegionInfo + { + public String name = ""; + + public String code = ""; + } + + public static class ImmutableRegionInfo + { + public final String name; + + public final String code; + + private ImmutableRegionInfo(RegionInfo base) + { + name = base.name; + code = base.code; + } + + public static ImmutableRegionInfo create(RegionInfo base) + { + if (base == null) + { + return null; + } + + return new ImmutableRegionInfo(base); + } + } + + public static class LocationInfo + { + @SerializedName("lat") + public double latitude = 0; + + @SerializedName("long") + public double longitude = 0; + } + + public static class ImmutableLocationInfo + { + @SerializedName("lat") + public final double latitude; + + @SerializedName("long") + public final double longitude; + + private ImmutableLocationInfo(LocationInfo base) + { + latitude = base.latitude; + longitude = base.longitude; + } + + public static ImmutableLocationInfo create(LocationInfo base) + { + if (base == null) + { + return null; + } + + return new ImmutableLocationInfo(base); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/IpBanNotification.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/IpBanNotification.java new file mode 100644 index 00000000..4ffa8c52 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/moderation/antialt/IpBanNotification.java @@ -0,0 +1,18 @@ +package mineplex.game.clans.clans.moderation.antialt; + +import mineplex.serverdata.commands.ServerCommand; + +public class IpBanNotification extends ServerCommand +{ + private final String _ip; + + public IpBanNotification(String ip) + { + _ip = ip; + } + + public String getIp() + { + return _ip; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java new file mode 100644 index 00000000..dd0315eb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java @@ -0,0 +1,471 @@ +package mineplex.game.clans.clans.mounts; + +import java.util.function.Consumer; + +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHorse; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse.Color; +import org.bukkit.entity.Horse.Style; +import org.bukkit.entity.Horse.Variant; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.TriConsumer; +import mineplex.core.common.util.C; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.particles.ColoredParticle; +import mineplex.core.common.util.particles.DustSpellColor; +import mineplex.core.disguise.disguises.DisguiseBase; +import mineplex.core.disguise.disguises.DisguiseBlock; +import mineplex.core.disguise.disguises.DisguiseCow; +import mineplex.core.disguise.disguises.DisguiseSheep; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClansManager; +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.GenericAttributes; + +public class Mount +{ + private static final long HIT_REGEN_COOLDOWN = 30000; + + private Player _owner; + private CraftHorse _entity; + private SkinType _skin; + private final int _strength; + private long _lastHit; + private int _hits; + + public Mount(Player owner, CraftHorse entity, SkinType skin, int strength) + { + _owner = owner; + _entity = entity; + _skin = skin; + _strength = strength; + _lastHit = System.currentTimeMillis(); + _hits = 0; + } + + public Player getOwner() + { + return _owner; + } + + public CraftHorse getEntity() + { + return _entity; + } + + public void update() + { + if (_skin != null) + { + _skin.onUpdate(_entity); + if (_skin.needsJumpAssist()) + { + EntityPlayer rider = null; + if (_entity.getPassenger() != null && _entity.getPassenger() instanceof Player) + { + rider = ((CraftPlayer)_entity.getPassenger()).getHandle(); + try + { + boolean jumping = MountManager.JumpBooleanField.getBoolean(rider); + + if (jumping) + { + rider.i(false); + if (UtilEnt.isGrounded(_entity)) + { + MountManager.JumpFloatField.setFloat(_entity.getHandle(), 1.0f); + } + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + } + } + if (UtilTime.elapsed(_lastHit, HIT_REGEN_COOLDOWN) && _hits > 0) + { + _hits--; + _lastHit = System.currentTimeMillis(); + } + } + + public void despawn(boolean forced) + { + UtilServer.CallEvent(new MountDespawnEvent(this, forced)); + _entity.getInventory().setSaddle(null); + _entity.getInventory().setArmor(null); + for (ItemStack item : _entity.getInventory().getContents()) + { + if (item == null || item.getType() == Material.AIR) + { + continue; + } + _entity.getWorld().dropItem(_entity.getLocation(), item); + } + _entity.remove(); + } + + public void handleHit() + { + _hits++; + if (_hits == _strength) + { + despawn(true); + } + } + + public static enum SkinType + { + INFERNAL_HORROR(1, "Clans Infernal Horror Mount Skin", C.cRed + "Infernal Horror", Material.BONE, Color.BLACK, Variant.SKELETON_HORSE, Style.BLACK_DOTS, false, horse -> {}, horse -> + { + UtilParticle.PlayParticleToAll(ParticleType.FLAME, horse.getLocation().add(0, 1, 0), + 0.25f, 0.25f, 0.25f, 0, 2,ViewDist.NORMAL); + }, MountType.HORSE), + GLACIAL_STEED(2, "Clans Glacial Steed Mount Skin", C.cGray + "Glacial Steed", Material.SNOW_BALL, Color.WHITE, Variant.HORSE, Style.WHITE, false, horse -> {}, horse -> + { + UtilParticle.PlayParticleToAll(ParticleType.SNOW_SHOVEL, horse.getLocation().add(0, 1, 0), + 0.25f, 0.25f, 0.25f, 0.1f, 4, ViewDist.NORMAL); + }, MountType.HORSE), + ZOMBIE_HORSE(3, "Clans Zombie Horse Mount Skin", C.cDGray + "Zombie Horse", Material.ROTTEN_FLESH, Color.BLACK, Variant.UNDEAD_HORSE, Style.BLACK_DOTS, false, horse -> {}, horse -> + { + UtilParticle.PlayParticleToAll(ParticleType.FOOTSTEP, horse.getLocation(), + null, 0, 1, ViewDist.NORMAL); + }, MountType.HORSE), + @SuppressWarnings("deprecation") + RAINBOW_SHEEP(4, "Clans Rainbow Sheep Mount Skin", C.cGreen + "Rainbow " + C.cAqua + "Sheep", new ItemBuilder(Material.WOOL).setData(DyeColor.RED.getWoolData()).build(),Color.WHITE, Variant.HORSE, Style.NONE, true, horse -> + { + DisguiseSheep disguise = new DisguiseSheep(horse); + disguise.setName(horse.getCustomName()); + ClansManager.getInstance().getDisguiseManager().disguise(disguise); + UtilEnt.SetMetadata(horse, "RainbowSheep.ActiveTicks", new EnclosedObject<>(0)); + UtilEnt.SetMetadata(horse, "RainbowSheep.DelayTicks", new EnclosedObject<>(0)); + UtilEnt.SetMetadata(horse, "RainbowSheep.ParticleColor", new EnclosedObject<>(java.awt.Color.RED)); + }, horse -> + { + EnclosedObject activeTicks = null; + EnclosedObject delayTicks = null; + EnclosedObject color = UtilEnt.GetMetadata(horse, "RainbowSheep.ParticleColor"); + if ((activeTicks = UtilEnt.GetMetadata(horse, "RainbowSheep.ActiveTicks")) != null && (delayTicks = UtilEnt.GetMetadata(horse, "RainbowSheep.DelayTicks")) != null) + { + DisguiseBase base = ClansManager.getInstance().getDisguiseManager().getActiveDisguise(horse); + if (base instanceof DisguiseSheep && (delayTicks.Get() % 10) == 0) + { + DisguiseSheep sheep = (DisguiseSheep) base; + int mod = activeTicks.Get() % 4; + activeTicks.Set(activeTicks.Get() + 1); + + if (mod == 0) + { + sheep.setColor(DyeColor.RED); + color.Set(java.awt.Color.RED); + } + else if (mod == 1) + { + sheep.setColor(DyeColor.YELLOW); + color.Set(java.awt.Color.YELLOW); + } + else if (mod == 2) + { + sheep.setColor(DyeColor.GREEN); + color.Set(java.awt.Color.GREEN); + } + else if (mod == 3) + { + sheep.setColor(DyeColor.BLUE); + color.Set(java.awt.Color.BLUE); + } + + ClansManager.getInstance().getDisguiseManager().updateDisguise(base); + } + delayTicks.Set(delayTicks.Get() + 1); + } + ColoredParticle particle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, + new DustSpellColor(color.Get()), horse.getLocation().add(0, 1, 0)); + particle.display(3); + }, MountType.HORSE), + ROYAL_STEED(5, "Clans Royal Steed Mount Skin", C.cGold + "Royal Steed", Material.DIAMOND_BARDING, Color.WHITE, Variant.HORSE, Style.WHITE, false, horse -> + { + horse.getInventory().setArmor(new ItemBuilder(Material.DIAMOND_BARDING).setTitle(C.cGoldB + "Royal Armor").build()); + }, horse -> + { + UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.GOLD_BLOCK, 0), horse.getLocation().add(0, 1, 0), + 0.25f, 0.25f, 0.25f, 0, 3, ViewDist.NORMAL); + }, MountType.HORSE), + ROYAL_GUARD_STEED(6, "Clans Royal Guard Steed Mount Skin", C.cGray + "Royal Guard's Steed", Material.GOLD_BARDING, Color.BLACK, Variant.HORSE, Style.NONE, false, horse -> + { + horse.getInventory().setArmor(new ItemBuilder(Material.GOLD_BARDING).setTitle(C.cGoldB + "Guardian Armor").build()); + }, horse -> + { + UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.IRON_BLOCK, 0), horse.getLocation().add(0, 1, 0), + 0.25f, 0.25f, 0.25f, 0, 3, ViewDist.NORMAL); + }, MountType.HORSE), + KNIGHT_STEED(7, "Clans Knight Steed Mount Skin", C.cDRed + "Knight's Steed", Material.IRON_BARDING, Color.GRAY, Variant.HORSE, Style.NONE, false, horse -> + { + horse.getInventory().setArmor(new ItemBuilder(Material.IRON_BARDING).setTitle(C.cGoldB + "Knightly Armor").build()); + }, horse -> + { + ColoredParticle red = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, + new DustSpellColor(java.awt.Color.RED), horse.getLocation().add(0, 1, 0)); + red.display(3); + }, MountType.HORSE), + COW(8, "Clans Cow Mount Skin", C.cWhite + "Cow", Material.MILK_BUCKET, Color.WHITE, Variant.HORSE, Style.NONE, true, horse -> + { + DisguiseCow disguise = new DisguiseCow(horse); + disguise.setName(horse.getCustomName()); + ClansManager.getInstance().getDisguiseManager().disguise(disguise); + }, horse -> {}, MountType.HORSE), + SHEEP(9, "Clans Sheep Mount Skin", C.cWhite + "Sheep", Material.WOOL, Color.WHITE, Variant.HORSE, Style.NONE, true, horse -> + { + DisguiseSheep disguise = new DisguiseSheep(horse); + disguise.setName(horse.getCustomName()); + ClansManager.getInstance().getDisguiseManager().disguise(disguise); + }, horse -> {}, MountType.HORSE), + TRUSTY_MULE(10, "Clans Trusty Mule Mount Skin", C.cBlue + "Trusty Mule", Material.APPLE, Color.BROWN, Variant.MULE, Style.NONE, false, horse -> {}, horse -> {}, MountType.DONKEY), + CAKE(11, "Clans Cake Mount Skin", C.cPurple + "Cake", Material.CAKE, Color.WHITE, Variant.HORSE, Style.NONE, true, horse -> + { + DisguiseBlock disguise = new DisguiseBlock(horse, Material.CAKE_BLOCK, 0); + ClansManager.getInstance().getDisguiseManager().disguise(disguise); + }, horse -> + { + ColoredParticle red = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, + new DustSpellColor(java.awt.Color.RED), horse.getLocation().add(0, 1, 0)); + red.display(2); + ColoredParticle white = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, + new DustSpellColor(java.awt.Color.WHITE), horse.getLocation().add(0, 1, 0)); + white.display(3); + + horse.getWorld().playSound(horse.getLocation(), Sound.EAT, 1, 1); + }, MountType.HORSE), + MELON(12, "Clans Power Melon Mount Skin", C.cGreen + "Power Melon", Material.MELON, Color.WHITE, Variant.HORSE, Style.NONE, true, horse -> + { + DisguiseBlock disguise = new DisguiseBlock(horse, Material.MELON_BLOCK, 0); + ClansManager.getInstance().getDisguiseManager().disguise(disguise); + UtilEnt.addFlag(horse, "HelmetPacket.RiderMelon"); + }, horse -> + { + ColoredParticle red = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, + new DustSpellColor(java.awt.Color.RED), horse.getLocation().add(0, 1, 0)); + red.display(2); + ColoredParticle green = new ColoredParticle(UtilParticle.ParticleType.RED_DUST, + new DustSpellColor(java.awt.Color.GREEN), horse.getLocation().add(0, 1, 0)); + green.display(3); + }, MountType.HORSE), + ; + + private final int _id; + private final String _packageName; + private final String _displayName; + private final ItemStack _baseDisplayItem; + private final Color _color; + private final Variant _variant; + private final Style _style; + private final boolean _needsJumpAssist; + private final Consumer _onSpawn, _onUpdate; + private final MountType[] _possibleTypes; + + private SkinType(int id, String packageName, String displayName, Material displayType, Color color, Variant variant, Style style, boolean needsJumpAssist, Consumer onSpawn, Consumer onUpdate, MountType... possibleTypes) + { + this(id, packageName, displayName, new ItemStack(displayType), color, variant, style, needsJumpAssist, onSpawn, onUpdate, possibleTypes); + } + + private SkinType(int id, String packageName, String displayName, ItemStack baseDisplayItem, Color color, Variant variant, Style style, boolean needsJumpAssist, Consumer onSpawn, Consumer onUpdate, MountType... possibleTypes) + { + _id = id; + _packageName = packageName; + _displayName = displayName; + _baseDisplayItem = baseDisplayItem; + _color = color; + _variant = variant; + _style = style; + _needsJumpAssist = needsJumpAssist; + _onSpawn = onSpawn; + _onUpdate = onUpdate; + _possibleTypes = possibleTypes; + } + + public int getId() + { + return _id; + } + + public String getPackageName() + { + return _packageName; + } + + public String getDisplayName() + { + return _displayName; + } + + public ItemStack getBaseDisplay() + { + return _baseDisplayItem; + } + + public Color getColor() + { + return _color; + } + + public Variant getVariant() + { + return _variant; + } + + public Style getStyle() + { + return _style; + } + + public boolean needsJumpAssist() + { + return _needsJumpAssist; + } + + public void onSpawn(CraftHorse horse) + { + _onSpawn.accept(horse); + } + + public void onUpdate(CraftHorse horse) + { + _onUpdate.accept(horse); + } + + public MountType[] getPossibleTypes() + { + return _possibleTypes; + } + + public static SkinType getFromId(int id) + { + for (SkinType type : SkinType.values()) + { + if (type.getId() == id) + { + return type; + } + } + + return null; + } + } + + public static enum MountType + { + HORSE(1, C.cWhite + "Horse", Material.IRON_BARDING, (owner, skin, stats) -> + { + CraftHorse horse = (CraftHorse) owner.getWorld().spawnEntity(owner.getLocation(), EntityType.HORSE); + horse.setAdult(); + horse.setAgeLock(true); + horse.setBreed(false); + horse.setCustomNameVisible(true); + horse.setCustomName(owner.getName() + "'s " + (skin == null ? "Horse" : ChatColor.stripColor(skin.getDisplayName()))); + if (skin != null) + { + horse.setVariant(skin.getVariant()); + horse.setColor(skin.getColor()); + horse.setStyle(skin.getStyle()); + skin.onSpawn(horse); + } + horse.setTamed(true); + horse.getInventory().setSaddle(new ItemStack(Material.SADDLE)); + horse.setOwner(owner); + horse.setJumpStrength(MountManager.getJump(stats.JumpStars)); + horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MountManager.getSpeed(stats.SpeedStars)); + //horse.setPassenger(owner); + Mount mount = new Mount(owner, horse, skin, MountManager.getStrength(stats.StrengthStars)); + UtilServer.CallEvent(new MountSpawnEvent(mount)); + }), + DONKEY(2, C.cWhite + "Donkey", Material.GOLD_BARDING, (owner, skin, stats) -> + { + CraftHorse horse = (CraftHorse) owner.getWorld().spawnEntity(owner.getLocation(), EntityType.HORSE); + horse.setAdult(); + horse.setAgeLock(true); + horse.setBreed(false); + horse.setCustomNameVisible(true); + horse.setCustomName(owner.getName() + "'s " + (skin == null ? "Donkey" : ChatColor.stripColor(skin.getDisplayName()))); + if (skin != null) + { + horse.setVariant(skin.getVariant()); + skin.onSpawn(horse); + } + else + { + horse.setVariant(Variant.DONKEY); + } + horse.setTamed(true); + horse.getInventory().setSaddle(new ItemStack(Material.SADDLE)); + horse.setOwner(owner); + horse.setJumpStrength(MountManager.getJump(stats.JumpStars)); + horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MountManager.getSpeed(stats.SpeedStars)); + horse.setCarryingChest(true); + //horse.setPassenger(owner); + Mount mount = new Mount(owner, horse, skin, MountManager.getStrength(stats.StrengthStars)); + UtilServer.CallEvent(new MountSpawnEvent(mount)); + }) + ; + + private final int _id; + private final String _displayName; + private final Material _displayType; + private final TriConsumer _spawnHandler; + + private MountType(int id, String displayName, Material displayType, TriConsumer spawnHandler) + { + _id = id; + _displayName = displayName; + _displayType = displayType; + _spawnHandler = spawnHandler; + } + + public int getId() + { + return _id; + } + + public String getDisplayName() + { + return _displayName; + } + + public Material getDisplayType() + { + return _displayType; + } + + public void spawn(Player owner, SkinType skinType, MountStatToken statToken) + { + _spawnHandler.accept(owner, skinType, statToken); + } + + public static MountType getFromId(int id) + { + for (MountType type : MountType.values()) + { + if (type.getId() == id) + { + return type; + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountClaimToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountClaimToken.java new file mode 100644 index 00000000..47a98ae5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountClaimToken.java @@ -0,0 +1,103 @@ +package mineplex.game.clans.clans.mounts; + +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.mounts.Mount.MountType; + +public class MountClaimToken +{ + private final String STAR = "✩"; + + public final int JumpStars; + public final int SpeedStars; + public final int StrengthStars; + public final MountType Type; + + public MountClaimToken(int jumpStars, int speedStars, int strengthStars, MountType type) + { + JumpStars = jumpStars; + SpeedStars = speedStars; + StrengthStars = strengthStars; + Type = type; + } + + public ItemStack toItem() + { + ItemBuilder builder = new ItemBuilder(Type.getDisplayType()); + builder.setTitle(Type.getDisplayName() + " Mount Token"); + String strength = C.cYellow; + for (int i = 0; i < StrengthStars; i++) + { + strength += STAR; + } + builder.addLore(C.cPurple + "Strength: " + strength); + String speed = C.cYellow; + for (int i = 0; i < SpeedStars; i++) + { + speed += STAR; + } + builder.addLore(C.cPurple + "Speed: " + speed); + String jump = C.cYellow; + for (int i = 0; i < JumpStars; i++) + { + jump += STAR; + } + builder.addLore(C.cPurple + "Jump: " + jump); + builder.addLore(C.cRed); + builder.addLore(C.cDGreen + "Right-Click While Holding to Consume"); + + return builder.build(); + } + + public static MountClaimToken fromItem(ItemStack item) + { + if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) + { + return null; + } + + MountType type = null; + for (MountType check : MountType.values()) + { + if (check.getDisplayType() == item.getType()) + { + type = check; + break; + } + } + if (type == null) + { + return null; + } + + int strength = -1; + int speed = -1; + int jump = -1; + + for (String lore : item.getItemMeta().getLore()) + { + if (ChatColor.stripColor(lore).startsWith("Strength: ")) + { + strength = ChatColor.stripColor(lore).replace("Strength: ", "").length(); + } + if (ChatColor.stripColor(lore).startsWith("Speed: ")) + { + speed = ChatColor.stripColor(lore).replace("Speed: ", "").length(); + } + if (ChatColor.stripColor(lore).startsWith("Jump: ")) + { + jump = ChatColor.stripColor(lore).replace("Jump: ", "").length(); + } + } + + if (strength <= 0 || speed <= 0 || jump <= 0) + { + return null; + } + + return new MountClaimToken(jump, speed, strength, type); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java new file mode 100644 index 00000000..5f89ed91 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java @@ -0,0 +1,41 @@ +package mineplex.game.clans.clans.mounts; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Event called before a mount despawns + */ +public class MountDespawnEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private final Mount _mount; + private final boolean _forced; + + public MountDespawnEvent(Mount mount, boolean forced) + { + _mount = mount; + _forced = forced; + } + + public Mount getMount() + { + return _mount; + } + + public boolean isForced() + { + return _forced; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java new file mode 100644 index 00000000..f35f8cb7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java @@ -0,0 +1,654 @@ +package mineplex.game.clans.clans.mounts; + +import java.lang.reflect.Field; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.WeakHashMap; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHorse; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.HorseInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.spigotmc.event.entity.EntityDismountEvent; + +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.command.CommandBase; +import mineplex.core.common.Pair; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.donation.DonationManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.HelmetPacketManager; +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.clans.mounts.Mount.SkinType; +import mineplex.game.clans.clans.mounts.gui.MountShop; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.spawn.Spawn; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.serverdata.Utility; +import net.minecraft.server.v1_8_R3.EntityHorse; +import net.minecraft.server.v1_8_R3.EntityLiving; + +public class MountManager extends MiniDbClientPlugin +{ + public enum Perm implements Permission + { + MOUNT_COMMAND, + GIVE_MOUNT_COMMAND, + MOUNT_SKIN_UNLOCK, + } + + protected static Field JumpBooleanField; + protected static Field JumpFloatField; + + private static final double[] JUMP_STARS = {0.8, 1, 1.2}; + private static final double[] SPEED_STARS = {0.2, 0.27, 0.33}; + private static final int[] STRENGTH_STARS = {1, 2, 3}; + + private static final long SUMMON_WARMUP = 5000; + private static final long FORCED_COOLDOWN = 120 * 1000; + private static final long MAX_TIME_DISMOUNTED = 30000; + + private static final int MAX_PER_TYPE = 3; + + private final MountRepository _repository; + private final DonationManager _donationManager; + + private final Map _spawnedMounts = new HashMap<>(); + private final Map> _summoning = new WeakHashMap<>(); + + private final int _serverId; + + public MountManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super("Clans Mount Manager", plugin, clientManager); + + try + { + JumpBooleanField = EntityLiving.class.getDeclaredField("aY"); + JumpBooleanField.setAccessible(true); + JumpFloatField = EntityHorse.class.getDeclaredField("br"); + JumpFloatField.setAccessible(true); + } + catch (NoSuchFieldException e) + { + e.printStackTrace(); + } + _serverId = ClansManager.getInstance().getServerId(); + _repository = new MountRepository(plugin, this, _serverId); + _donationManager = donationManager; + + final MountShop shop = new MountShop(this); + + addCommand(new CommandBase(this, Perm.MOUNT_COMMAND, "mounts", "mount") + { + @Override + public void Execute(Player caller, String[] args) + { + shop.attemptShopOpen(caller); + } + }); + + addCommand(new CommandBase(this, Perm.GIVE_MOUNT_COMMAND, "givemount") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 4) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /" + _aliasUsed + " ")); + return; + } + + Integer speed = 0; + Integer jump = 0; + Integer strength = 0; + MountType type = null; + + try + { + speed = Integer.parseInt(args[0]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid speed!")); + return; + } + + try + { + jump = Integer.parseInt(args[1]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid jump!")); + return; + } + + try + { + strength = Integer.parseInt(args[2]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid strength!")); + return; + } + + try + { + type = MountType.valueOf(args[3]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid type!")); + return; + } + + caller.getInventory().addItem(new MountClaimToken(jump, speed, strength, type).toItem()); + } + }); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.PLAYER.setPermission(Perm.MOUNT_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.GIVE_MOUNT_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.MOUNT_SKIN_UNLOCK, true, true); + } + + public DonationManager getDonationManager() + { + return _donationManager; + } + + public MountRepository getRepository() + { + return _repository; + } + + @Override + public void disable() + { + _summoning.clear(); + _spawnedMounts.keySet().forEach(CraftHorse::remove); + _spawnedMounts.clear(); + } + + public boolean summonMount(Player player, MountToken token) + { + if (_summoning.containsKey(player)) + { + UtilPlayer.message(player, F.main(getName(), "You are already summoning a mount!")); + return false; + } + if (Spawn.getInstance().isSafe(player.getLocation())) + { + UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount in safezones!")); + return false; + } + if (ClansManager.getInstance().getNetherManager().isInNether(player)) + { + UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount in the Nether!")); + return false; + } + if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount inside a raid!")); + return false; + } + for (double x = -2; x <= 2; x++) + { + for (double z = -2; z <= 2; z++) + { + Location loc = player.getLocation().add(x, 0, z); + ClanTerritory territory = ClansManager.getInstance().getClanUtility().getClaim(loc); + if (territory != null) + { + ClanInfo cInfo = ClansManager.getInstance().getClan(player); + if (cInfo != null && !cInfo.getName().equals(territory.Owner) && !ClansManager.getInstance().getClan(territory.Owner).isAdmin()) + { + UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount that close to another Clan's territory!")); + return false; + } + } + } + } + if (!Recharge.Instance.usable(player, "Mount Spawn Delay")) + { + UtilPlayer.message(player, F.main(getName(), "You cannot summon a mount so soon after your last one was forcibly despawned!")); + return false; + } + _spawnedMounts.values().stream().filter(mount -> mount.getOwner().getEntityId() == player.getEntityId()).findFirst().ifPresent(mount -> mount.despawn(false)); + _summoning.put(player, Pair.create(System.currentTimeMillis(), token)); + UtilPlayer.message(player, F.main(getName(), "You are now summoning your mount! Please remain still for 5 seconds!")); + return true; + } + + public void giveMount(Player player, MountType type) + { + Pair tokens = Get(player).grantMount(type); + _repository.saveMount(ClientManager.getAccountId(player), tokens.getLeft(), tokens.getRight()); + } + + public void giveMount(Player player, MountClaimToken token) + { + Pair tokens = Get(player).grantMount(token.Type, token.SpeedStars, token.JumpStars, token.StrengthStars); + _repository.saveMount(ClientManager.getAccountId(player), tokens.getLeft(), tokens.getRight()); + } + + public void removeMountToken(Player player, MountToken token, Runnable after) + { + getRepository().deleteMount(token, id -> + { + Get(player).removeMount(id); + Pair summonPair = _summoning.get(player); + if (summonPair != null) + { + if (summonPair.getRight().Id == id) + { + UtilEnt.addFlag(player, "REMOVED_MOUNT_TOKEN"); + } + } + after.run(); + }); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.TICK) + { + Iterator> mountIterator = _spawnedMounts.entrySet().iterator(); + while (mountIterator.hasNext()) + { + Entry entry = mountIterator.next(); + if (entry.getKey().isDead() || !entry.getKey().isValid()) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (entry.getValue().getOwner().isDead() || !entry.getValue().getOwner().isValid() || !entry.getValue().getOwner().isOnline()) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (Spawn.getInstance().isSafe(entry.getKey().getLocation())) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (ClansManager.getInstance().getNetherManager().isInNether(entry.getKey().getLocation())) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(entry.getKey().getLocation())) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (entry.getKey().getPassenger() == null) + { + if (UtilEnt.GetMetadata(entry.getKey(), "DISMOUNT_TIME") != null) + { + Long dismount = UtilEnt.GetMetadata(entry.getKey(), "DISMOUNT_TIME"); + if (UtilTime.elapsed(dismount, MAX_TIME_DISMOUNTED)) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + } + else + { + UtilEnt.SetMetadata(entry.getKey(), "DISMOUNT_TIME", System.currentTimeMillis()); + } + } + else + { + UtilEnt.removeMetadata(entry.getKey(), "DISMOUNT_TIME"); + } + entry.getValue().update(); + } + + Iterator>> summoningIterator = _summoning.entrySet().iterator(); + while (summoningIterator.hasNext()) + { + Entry> entry = summoningIterator.next(); + if (UtilEnt.hasFlag(entry.getKey(), "REMOVED_MOUNT_TOKEN")) + { + summoningIterator.remove(); + UtilEnt.removeFlag(entry.getKey(), "REMOVED_MOUNT_TOKEN"); + continue; + } + if (UtilTime.elapsed(entry.getValue().getLeft(), SUMMON_WARMUP)) + { + summoningIterator.remove(); + if (entry.getKey().isDead() || !entry.getKey().isValid() || !entry.getKey().isOnline()) + { + continue; + } + if (Spawn.getInstance().isSafe(entry.getKey().getLocation())) + { + continue; + } + if (ClansManager.getInstance().getNetherManager().isInNether(entry.getKey().getLocation())) + { + continue; + } + if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(entry.getKey().getLocation())) + { + continue; + } + entry.getValue().getRight().Type.spawn(entry.getKey(), entry.getValue().getRight().Skin, Get(entry.getKey()).getStatToken(entry.getValue().getRight())); + continue; + } + if (UtilEnt.hasFlag(entry.getKey(), "MOVED_WHILE_SUMMONING_MOUNT")) + { + summoningIterator.remove(); + UtilEnt.removeFlag(entry.getKey(), "MOVED_WHILE_SUMMONING_MOUNT"); + UtilPlayer.message(entry.getKey(), F.main(getName(), "You have stopped summoning your mount as you have moved!")); + continue; + } + } + } + } + + @EventHandler + public void onMove(PlayerMoveEvent event) + { + if (_summoning.containsKey(event.getPlayer()) && !UtilEnt.hasFlag(event.getPlayer(), "MOVED_WHILE_SUMMONING_MOUNT")) + { + Block from = event.getFrom().getBlock(); + Block to = event.getTo().getBlock(); + + if (from.getX() == to.getX() && from.getY() == to.getY() && from.getZ() == to.getZ()) + { + return; + } + UtilEnt.addFlag(event.getPlayer(), "MOVED_WHILE_SUMMONING_MOUNT"); + } + } + + @EventHandler + public void onSummon(MountSpawnEvent event) + { + _spawnedMounts.put(event.getMount().getEntity(), event.getMount()); + UtilPlayer.message(event.getMount().getOwner(), F.main(getName(), "Your mount has spawned!")); + } + + @EventHandler + public void onDespawn(MountDespawnEvent event) + { + _spawnedMounts.remove(event.getMount().getEntity()); + event.getMount().getEntity().eject(); + event.getMount().getEntity().remove(); + UtilPlayer.message(event.getMount().getOwner(), F.main(getName(), "Your mount has despawned!")); + if (event.isForced()) + { + Recharge.Instance.use(event.getMount().getOwner(), "Mount Spawn Delay", FORCED_COOLDOWN, false, false); + } + } + + @EventHandler + public void onUseToken(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R)) + { + return; + } + if (event.getItem() == null) + { + return; + } + MountClaimToken token = MountClaimToken.fromItem(event.getItem()); + if (token == null) + { + return; + } + + event.setCancelled(true); + + if (Get(event.getPlayer()).getAmountOwned(token.Type) >= MAX_PER_TYPE) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have reached the maximum amount of that type of mount!")); + return; + } + + giveMount(event.getPlayer(), token); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have redeemed your mount!")); + event.getPlayer().getInventory().setItemInHand(null); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void redirectHorseDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity() == null || !(event.GetDamageeEntity() instanceof Horse)) + { + return; + } + Mount mount = _spawnedMounts.get(event.GetDamageeEntity()); + if (mount == null) + { + return; + } + if (event.GetDamagerPlayer(true) != null && event.GetDamagerPlayer(true).getEntityId() == mount.getOwner().getEntityId()) + { + event.SetCancelled("Damaging own mount"); + mount.despawn(false); + return; + } + if (mount.getEntity().getPassenger() == null) + { + event.SetCancelled("Killing riderless mount"); + mount.despawn(true); + return; + } + event.setDamagee(mount.getOwner()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void handleRiderHits(CustomDamageEvent event) + { + if (event.GetDamageePlayer() == null || event.GetDamageePlayer().getVehicle() == null || !(event.GetDamageePlayer().getVehicle() instanceof Horse)) + { + return; + } + if (event.GetDamagerPlayer(true) != null && event.GetDamagerPlayer(true).getEntityId() == event.GetDamageePlayer().getEntityId()) + { + return; + } + Mount mount = _spawnedMounts.get(event.GetDamageePlayer().getVehicle()); + if (mount == null) + { + return; + } + if (event.GetCause() != DamageCause.FALL) + { + mount.handleHit(); + } + } + + @EventHandler + public void onEditHorseInventory(InventoryClickEvent event) + { + if (!(event.getClickedInventory() instanceof HorseInventory)) + { + return; + } + if (!_spawnedMounts.containsKey(event.getClickedInventory().getHolder())) + { + return; + } + if (event.getSlot() == 0 || event.getSlot() == 1) + { + event.setCancelled(true); + } + } + + @EventHandler + public void mountInteract(PlayerInteractEntityEvent event) + { + if (!(event.getRightClicked() instanceof Horse)) + { + return; + } + Mount mount = _spawnedMounts.get(event.getRightClicked()); + if (mount == null) + { + return; + } + if (mount.getOwner().getEntityId() == event.getPlayer().getEntityId()) + { + if (UtilEnt.hasFlag(event.getRightClicked(), "HelmetPacket.RiderMelon")) + { + HelmetPacketManager.getInstance().refreshToAll(event.getPlayer(), new ItemStack(Material.MELON_BLOCK)); + } + return; + } + + UtilPlayer.message(event.getPlayer(), F.main(getName(), "This is not your Mount!")); + event.setCancelled(true); + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) + { + _spawnedMounts.entrySet().forEach(entry -> + { + if (UtilWorld.isInChunk(entry.getKey().getLocation(), event.getChunk())) + { + entry.getValue().despawn(false); + } + }); + } + + @EventHandler + public void onDismount(EntityDismountEvent event) + { + if (_spawnedMounts.containsKey(event.getEntity()) && event.getDismounted() instanceof Player) + { + Player player = (Player) event.getDismounted(); + runSyncLater(() -> + { + player.teleport(event.getEntity()); + if (UtilEnt.hasFlag(event.getEntity(), "HelmetPacket.RiderMelon")) + { + HelmetPacketManager.getInstance().refreshToAll(player, null); + } + }, 1L); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onShootBow(EntityShootBowEvent event) + { + LivingEntity entity = event.getEntity(); + Entity vehicle = entity.getVehicle(); + if (entity instanceof Player && vehicle != null && _spawnedMounts.containsKey(vehicle)) + { + UtilPlayer.message(entity, F.main(getName(), "You cannot shoot while mounted!")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onUseSkill(SkillTriggerEvent event) + { + Player rider = event.GetPlayer(); + Entity vehicle = rider.getVehicle(); + if (vehicle != null && _spawnedMounts.containsKey(vehicle)) + { + UtilPlayer.message(rider, F.main(getName(), "You cannot use skills while mounted!")); + event.SetCancelled(true); + } + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT am.id, am.mountTypeId, am.mountSkinId, ms.statToken FROM accountClansMounts AS am INNER JOIN clansMountStats AS ms ON ms.mountId = am.id WHERE am.accountId=" + accountId + " AND am.serverId=" + _serverId + ";"; + } + + @Override + public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException + { + MountOwnerData data = new MountOwnerData(); + while (resultSet.next()) + { + MountToken token = new MountToken(); + token.Id = resultSet.getInt("id"); + token.Type = MountType.getFromId(resultSet.getInt("mountTypeId")); + token.Skin = SkinType.getFromId(resultSet.getInt("mountSkinId")); + MountStatToken statToken = Utility.deserialize(resultSet.getString("statToken"), MountStatToken.class); + data.acceptLoad(token, statToken); + } + Set(uuid, data); + } + + @Override + protected MountOwnerData addPlayer(UUID uuid) + { + return new MountOwnerData(); + } + + public static double getSpeed(int stars) + { + stars = Math.min(Math.max(1, stars), 3); + return SPEED_STARS[stars - 1]; + } + + public static double getJump(int stars) + { + stars = Math.min(Math.max(1, stars), 3); + return JUMP_STARS[stars - 1]; + } + + public static int getStrength(int stars) + { + stars = Math.min(Math.max(1, stars), 3); + return STRENGTH_STARS[stars - 1]; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java new file mode 100644 index 00000000..a048c4ba --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java @@ -0,0 +1,80 @@ +package mineplex.game.clans.clans.mounts; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.mounts.Mount.MountType; + +public class MountOwnerData +{ + private Map _mounts = new LinkedHashMap<>(); + + public List> getOwnedMounts(boolean onlyInitialized) + { + return _mounts.entrySet().stream().filter(entry -> onlyInitialized ? entry.getKey().Id != -1 : true).map(entry -> Pair.create(entry.getKey(), entry.getValue())).collect(Collectors.toList()); + } + + public List> getOwnedMounts(boolean onlyInitialized, MountType type) + { + return _mounts.entrySet().stream().filter(entry -> (onlyInitialized ? entry.getKey().Id != -1 : true) && type == entry.getKey().Type).map(entry -> Pair.create(entry.getKey(), entry.getValue())).collect(Collectors.toList()); + } + + public MountStatToken getStatToken(MountToken mountToken) + { + return _mounts.get(mountToken); + } + + public boolean ownsMount(MountType type) + { + return getAmountOwned(type) > 0; + } + + public long getAmountOwned(MountType type) + { + return _mounts.keySet().stream().filter(token -> token.Type == type).count(); + } + + public void acceptLoad(MountToken token, MountStatToken statToken) + { + _mounts.put(token, statToken); + } + + public Pair grantMount(MountType type, int speed, int jump, int strength) + { + MountToken token = new MountToken(); + token.Type = type; + MountStatToken statToken = new MountStatToken(); + statToken.JumpStars = jump; + statToken.SpeedStars = speed; + statToken.StrengthStars = strength; + _mounts.put(token, statToken); + + return Pair.create(token, statToken); + } + + public Pair grantMount(MountType type) + { + int speed = UtilMath.rRange(1, 3); + int jump = UtilMath.rRange(1, 3); + int strength = UtilMath.rRange(1, 3); + + return grantMount(type, speed, jump, strength); + } + + public Integer[] removeMounts(MountType type) + { + Integer[] array = _mounts.keySet().stream().filter(token->token.Type == type).map(token->token.Id).toArray(size->new Integer[size]); + _mounts.keySet().removeIf(token->token.Type == type); + + return array; + } + + public void removeMount(int id) + { + _mounts.keySet().removeIf(token->token.Id == id); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java new file mode 100644 index 00000000..2e797ae5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java @@ -0,0 +1,187 @@ +package mineplex.game.clans.clans.mounts; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.function.Consumer; + +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.Pair; +import mineplex.serverdata.Utility; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +/** + * Database repository class for mounts + */ +public class MountRepository extends RepositoryBase +{ + private static final String CREATE_MOUNTS_TABLE = "CREATE TABLE IF NOT EXISTS accountClansMounts (id INT NOT NULL AUTO_INCREMENT," + + "accountId INT NOT NULL," + + "serverId INT NOT NULL," + + "mountTypeId INT NOT NULL," + + "mountSkinId INT NOT NULL," + + "INDEX accountIndex (accountId)," + + "INDEX serverIndex (serverId)," + + "INDEX accountServerIndex(accountId, serverId)," + + "INDEX typeIndex (mountTypeId)," + + "INDEX skinIndex (mountSkinId)," + + "PRIMARY KEY (id));"; + + private static final String CREATE_MOUNT_STATS_TABLE = "CREATE TABLE IF NOT EXISTS clansMountStats (mountId INT NOT NULL," + + "statToken VARCHAR(20) NOT NULL," + + "PRIMARY KEY (mountId));"; + + private static final String INSERT_MOUNT = "INSERT INTO accountClansMounts (accountId, serverId, mountTypeId, mountSkinId) VALUES (?, ?, ?, ?);"; + private static final String SAVE_MOUNT = "UPDATE accountClansMounts SET mountSkinId=? WHERE id=?;"; + private static final String SAVE_MOUNT_STATS = "INSERT INTO clansMountStats (mountId, statToken) VALUES (?, ?) ON DUPLICATE KEY UPDATE statToken=VALUES(statToken);"; + private static final String DELETE_MOUNT = "DELETE FROM accountClansMounts WHERE id=?;"; + private static final String DELETE_MOUNT_STATS = "DELETE FROM clansMountStats WHERE mountId=?;"; + + private final int _serverId; + private MountManager _mountManager; + + public MountRepository(JavaPlugin plugin, MountManager mountManager, int serverId) + { + super(DBPool.getAccount()); + + _mountManager = mountManager; + _serverId = serverId; + } + + /** + * Saves a mount into the database + * @param accountId The owner's account id + * @param token The mount token to save + * @param statToken The stat token to save + */ + public void saveMount(final int accountId, final MountToken token, final MountStatToken statToken) + { + _mountManager.runAsync(() -> + { + try (Connection connection = getConnection();) + { + if (token.Id == -1) + { + executeInsert(connection, INSERT_MOUNT, idResult -> + { + if (idResult.next()) + { + token.Id = idResult.getInt(1); + } + }, null, new ColumnInt("accountId", accountId), new ColumnInt("serverId", _serverId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId())); + } + else + { + executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()), new ColumnInt("id", token.Id)); + } + if (token.Id == -1) + { + return; + } + executeUpdate(connection, SAVE_MOUNT_STATS, null, new ColumnInt("mountId", token.Id), new ColumnVarChar("statToken", 20, Utility.serialize(statToken))); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + /** + * Saves a list of mounts into the database + * @param accountId The owner's account id + * @param tokens The list of token pairs to save + */ + public void saveMounts(final int accountId, final List> tokens) + { + _mountManager.runAsync(() -> + { + try (Connection connection = getConnection()) + { + for (Pair tokenPair : tokens) + { + MountToken token = tokenPair.getLeft(); + MountStatToken statToken = tokenPair.getRight(); + + if (token.Id == -1) + { + executeInsert(connection, INSERT_MOUNT, idResult -> + { + if (idResult.next()) + { + token.Id = idResult.getInt(1); + } + }, null, new ColumnInt("accountId", accountId), new ColumnInt("serverId", _serverId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId())); + } + else + { + executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()), new ColumnInt("id", token.Id)); + } + if (token.Id == -1) + { + continue; + } + executeUpdate(connection, SAVE_MOUNT_STATS, null, new ColumnInt("mountId", token.Id), new ColumnVarChar("statToken", 100, Utility.serialize(statToken))); + } + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + /** + * Deletes a mount from the database + * @param token The mount to delete + */ + public void deleteMount(final MountToken token, final Consumer after) + { + if (token.Id == -1) + { + return; + } + _mountManager.runAsync(() -> + { + executeUpdate(DELETE_MOUNT, new ColumnInt("id", token.Id)); + executeUpdate(DELETE_MOUNT_STATS, new ColumnInt("mountId", token.Id)); + if (after != null) + { + _mountManager.runSync(() -> + { + after.accept(token.Id); + }); + } + }); + } + + /** + * Deletes an array from the database + * @param ids The mount ids to delete + */ + public void deleteMounts(final int[] ids, final Runnable after) + { + if (ids.length <= 0) + { + return; + } + _mountManager.runAsync(() -> + { + String idList = ids[0] + ""; + for (int i = 1; i < ids.length; i++) + { + idList += ("," + ids[i]); + } + executeUpdate(DELETE_MOUNT.replace("id=?;", "id IN (" + idList + ");")); + executeUpdate(DELETE_MOUNT_STATS.replace("mountId=?;", "mountId IN (" + idList + ");")); + if (after != null) + { + _mountManager.runSync(after); + } + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountSpawnEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountSpawnEvent.java new file mode 100644 index 00000000..b77ae1da --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountSpawnEvent.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.clans.mounts; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Event called after a mount spawns + */ +public class MountSpawnEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private final Mount _mount; + + public MountSpawnEvent(Mount mount) + { + _mount = mount; + } + + public Mount getMount() + { + return _mount; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java new file mode 100644 index 00000000..14b713a0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java @@ -0,0 +1,8 @@ +package mineplex.game.clans.clans.mounts; + +public class MountStatToken +{ + public int JumpStars = 1; + public int SpeedStars = 1; + public int StrengthStars = 1; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountToken.java new file mode 100644 index 00000000..c8732b38 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountToken.java @@ -0,0 +1,11 @@ +package mineplex.game.clans.clans.mounts; + +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.clans.mounts.Mount.SkinType; + +public class MountToken +{ + public int Id = -1; + public MountType Type = null; + public SkinType Skin = null; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountOverviewPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountOverviewPage.java new file mode 100644 index 00000000..e3e1021c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountOverviewPage.java @@ -0,0 +1,166 @@ +package mineplex.game.clans.clans.mounts.gui; + +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.shop.confirmation.ConfirmationCallback; +import mineplex.core.shop.confirmation.ConfirmationPage; +import mineplex.core.shop.confirmation.ConfirmationProcessor; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.clans.mounts.MountManager; +import mineplex.game.clans.clans.mounts.MountStatToken; +import mineplex.game.clans.clans.mounts.MountToken; + +public class MountOverviewPage extends ShopPageBase +{ + private final String STAR = "✩"; + + public MountOverviewPage(MountManager plugin, MountShop shop, String name, Player player) + { + super(plugin, shop, plugin.getClientManager(), plugin.getDonationManager(), name, player, 27); + + buildPage(); + } + + private ItemStack toItem(MountToken mountToken, MountStatToken statToken, boolean overview) + { + ItemBuilder builder = new ItemBuilder(mountToken.Type.getDisplayType()); + builder.setTitle(mountToken.Type.getDisplayName() + " Mount"); + builder.addLore(C.cPurple + "Skin: " + (mountToken.Skin == null ? C.cYellow + "Default" : mountToken.Skin.getDisplayName())); + String strength = C.cYellow; + for (int i = 0; i < statToken.StrengthStars; i++) + { + strength += STAR; + } + builder.addLore(C.cPurple + "Strength: " + strength); + String speed = C.cYellow; + for (int i = 0; i < statToken.SpeedStars; i++) + { + speed += STAR; + } + builder.addLore(C.cPurple + "Speed: " + speed); + String jump = C.cYellow; + for (int i = 0; i < statToken.JumpStars; i++) + { + jump += STAR; + } + builder.addLore(C.cPurple + "Jump: " + jump); + if (overview) + { + builder.addLore(C.cRed); + builder.addLore(C.cDGreen + "Left-Click to Summon"); + builder.addLore(C.cDGreen + "Right-Click to Manage Skin"); + builder.addLore(C.cDRed + "Shift Right-Click to Destroy"); + } + + return builder.build(); + } + + @Override + protected void buildPage() + { + int[] horseSlots = {10, 11, 12}; + List> horses = getPlugin().Get(getPlayer()).getOwnedMounts(true, MountType.HORSE); + int[] donkeySlots = {14, 15, 16}; + List> donkeys = getPlugin().Get(getPlayer()).getOwnedMounts(true, MountType.DONKEY); + + for (int i = 0; i < horseSlots.length; i++) + { + int slot = horseSlots[i]; + ItemStack item = new ItemBuilder(Material.INK_SACK).setData((short)8).setTitle(C.cRed).build(); + IButton button = null; + if (horses.size() > i) + { + Pair tokens = horses.get(i); + item = toItem(tokens.getLeft(), tokens.getRight(), true); + button = (player, clickType) -> + { + if (clickType == ClickType.LEFT) + { + if (!getPlugin().summonMount(player, tokens.getLeft())) + { + playDenySound(player); + } + } + else if (clickType == ClickType.RIGHT) + { + getShop().openPageForPlayer(player, new MountSkinPage(this, player, tokens.getLeft())); + } + else if (clickType == ClickType.SHIFT_RIGHT) + { + getShop().openPageForPlayer(player, new ConfirmationPage(player, MountOverviewPage.this, new ConfirmationProcessor() + { + @Override + public void init(Inventory inventory) {} + + @Override + public void process(ConfirmationCallback callback) + { + getPlugin().removeMountToken(player, tokens.getLeft(), () -> + { + MountOverviewPage.this.refresh(); + callback.resolve("Mount successfully deleted!"); + }); + } + }, toItem(tokens.getLeft(), tokens.getRight(), false))); + } + }; + } + addButton(slot, item, button); + } + for (int i = 0; i < donkeySlots.length; i++) + { + int slot = donkeySlots[i]; + ItemStack item = new ItemBuilder(Material.INK_SACK).setData((short)8).setTitle(C.cRed).build(); + IButton button = null; + if (donkeys.size() > i) + { + Pair tokens = donkeys.get(i); + item = toItem(tokens.getLeft(), tokens.getRight(), true); + button = (player, clickType) -> + { + if (clickType == ClickType.LEFT) + { + if (!getPlugin().summonMount(player, tokens.getLeft())) + { + playDenySound(player); + } + } + else if (clickType == ClickType.RIGHT) + { + getShop().openPageForPlayer(player, new MountSkinPage(this, player, tokens.getLeft())); + } + else if (clickType == ClickType.SHIFT_RIGHT) + { + getShop().openPageForPlayer(player, new ConfirmationPage(player, new MountOverviewPage(getPlugin(), getShop(), getName(), getPlayer()), new ConfirmationProcessor() + { + @Override + public void init(Inventory inventory) {} + + @Override + public void process(ConfirmationCallback callback) + { + getPlugin().removeMountToken(player, tokens.getLeft(), () -> + { + MountOverviewPage.this.refresh(); + callback.resolve("Mount successfully deleted!"); + }); + } + }, toItem(tokens.getLeft(), tokens.getRight(), false))); + } + }; + } + addButton(slot, item, button); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountShop.java new file mode 100644 index 00000000..d6dd454d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountShop.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.clans.mounts.gui; + +import org.bukkit.entity.Player; + +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.mounts.MountManager; + +public class MountShop extends ShopBase +{ + public MountShop(MountManager plugin) + { + super(plugin, plugin.getClientManager(), plugin.getDonationManager(), "Manage Mounts"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new MountOverviewPage(getPlugin(), this, "Manage Mounts", player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountSkinPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountSkinPage.java new file mode 100644 index 00000000..757fec95 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountSkinPage.java @@ -0,0 +1,141 @@ +package mineplex.game.clans.clans.mounts.gui; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.mounts.Mount.SkinType; +import mineplex.game.clans.clans.mounts.MountManager; +import mineplex.game.clans.clans.mounts.MountToken; + +public class MountSkinPage extends ShopPageBase +{ + private MountOverviewPage _overview; + private MountToken _token; + + public MountSkinPage(MountOverviewPage overview, Player player, MountToken token) + { + super(overview.getPlugin(), overview.getShop(), overview.getClientManager(), overview.getDonationManager(), "Skin Management", player, 54); + + _overview = overview; + _token = token; + buildPage(); + } + + private List getAllowed() + { + List allowed = new LinkedList<>(); + + for (SkinType type : SkinType.values()) + { + if (Arrays.asList(type.getPossibleTypes()).contains(_token.Type)) + { + allowed.add(type); + } + } + + return allowed; + } + + private boolean hasUnlocked(Player player, SkinType type) + { + if (getClientManager().Get(player).hasPermission(MountManager.Perm.MOUNT_SKIN_UNLOCK)) + { + return true; + } + + return getDonationManager().Get(player).ownsUnknownSalesPackage(type.getPackageName()); + } + + private boolean hasUnlocked(SkinType type) + { + return hasUnlocked(getPlayer(), type); + } + + private ItemStack buildResetItem() + { + ItemBuilder builder = new ItemBuilder(Material.PAPER); + + builder.setTitle(C.cYellow + "Default Skin"); + if (_token.Skin == null) + { + builder.setLore(C.cRed, C.cGreenB + "SELECTED"); + } + + return builder.build(); + } + + private ItemStack buildSkinItem(SkinType type) + { + ItemBuilder builder = new ItemBuilder(type.getBaseDisplay()); + + builder.setTitle(type.getDisplayName()); + builder.setLore(C.cRed); + if (_token.Skin == type) + { + builder.addLore(C.cGreenB + "SELECTED"); + } + else if (hasUnlocked(type)) + { + builder.addLore(C.cGreenB + "UNLOCKED"); + } + else + { + builder.addLore(C.cGray + "Available at http://www.mineplex.com/shop"); + builder.addLore(C.cRedB + "LOCKED"); + } + + return builder.build(); + } + + @Override + protected void buildPage() + { + addButton(0, new ItemBuilder(Material.BED).setTitle(C.cGreen + "Back").build(), (player, clickType) -> + { + _overview.refresh(); + getShop().openPageForPlayer(player, _overview); + }); + addButton(13, buildResetItem(), (player, clickType) -> + { + if (_token.Skin == null) + { + playDenySound(player); + } + else + { + playAcceptSound(player); + _token.Skin = null; + getPlugin().getRepository().saveMount(getClientManager().Get(player).getAccountId(), _token, getPlugin().Get(player).getStatToken(_token)); + refresh(); + } + }); + int[] skinSlots = {20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 38, 39, 40, 41, 42}; + List allowed = getAllowed(); + for (int i = 0; i < skinSlots.length && i < allowed.size(); i++) + { + SkinType type = allowed.get(i); + addButton(skinSlots[i], buildSkinItem(type), (player, clickType) -> + { + if (hasUnlocked(player, type) && _token.Skin != type) + { + playAcceptSound(player); + _token.Skin = type; + getPlugin().getRepository().saveMount(getClientManager().Get(player).getAccountId(), _token, getPlugin().Get(player).getStatToken(_token)); + refresh(); + } + else + { + playDenySound(player); + } + }); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/murder/ClientMurder.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/murder/ClientMurder.java new file mode 100644 index 00000000..3377a54b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/murder/ClientMurder.java @@ -0,0 +1,52 @@ +package mineplex.game.clans.clans.murder; + +public class ClientMurder +{ + private boolean _isWeakling; + private long _lastWeaklingUpdate; + private long _ignoreWeaklingTime; + private int _inventoryValue; + + public ClientMurder() + { + } + + public boolean isWeakling() + { + return _isWeakling && _ignoreWeaklingTime < System.currentTimeMillis(); + } + + public void setIsWeakling(boolean isWeakling) + { + _isWeakling = isWeakling; + _lastWeaklingUpdate = System.currentTimeMillis(); + } + + public void setInventoryValue(int inventoryValue) + { + _inventoryValue = inventoryValue; + } + + /** + * Disable weakling status for x milliseconds + * + * @param milliseconds + */ + public void disableWeakling(long milliseconds) + { + if (_ignoreWeaklingTime > System.currentTimeMillis()) + _ignoreWeaklingTime += milliseconds; + else + _ignoreWeaklingTime = System.currentTimeMillis() + milliseconds; + } + + public long getLastWeaklingUpdate() + { + return _lastWeaklingUpdate; + } + + public int getInventoryValue() + { + return _inventoryValue; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/murder/MurderManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/murder/MurderManager.java new file mode 100644 index 00000000..3e7735e0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/murder/MurderManager.java @@ -0,0 +1,212 @@ +package mineplex.game.clans.clans.murder; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniClientPlugin; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.shop.ClansShopItem; +import mineplex.minecraft.game.core.combat.CombatComponent; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; + +public class MurderManager extends MiniClientPlugin +{ + private final List weapons = Arrays.asList(Material.WOOD_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.DIAMOND_SWORD, Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.DIAMOND_AXE, Material.BOW); + + private final List armor = Arrays.asList(Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS); + + private ClansManager _clansManager; + + public MurderManager(JavaPlugin plugin, ClansManager clansManager) + { + super("Murder", plugin); + + _clansManager = clansManager; + } + + @EventHandler + public void onCombatDeath(CombatDeathEvent event) + { + if (event.GetEvent().getEntity() instanceof Player) + { + Player deadPlayer = ((Player) event.GetEvent().getEntity()); + refreshClient(deadPlayer); + Location location = deadPlayer.getLocation(); + + CombatComponent combatKiller = event.GetLog().GetKiller(); + if (combatKiller != null && combatKiller.IsPlayer()) + { + Player killer = UtilPlayer.searchExact(combatKiller.GetName()); + if (killer != null) + { + refreshClient(deadPlayer); + refreshClient(killer); + if (canMurderOccur(killer, deadPlayer, location) && isWeakling(deadPlayer) && !isWeakling(killer)) + { + // Was a murder + event.setKilledWord("murdered"); + ClanInfo killerClan = _clansManager.getClan(killer); + + if (killerClan != null) killerClan.addMurder(1); + } + } + } + } + } + + @EventHandler (ignoreCancelled = true) + public void onPickup(PlayerPickupItemEvent event) + { + refreshClient(event.getPlayer()); + } + + @EventHandler + public void onDrop(PlayerDropItemEvent event) + { + refreshClient(event.getPlayer()); + } + + @EventHandler + public void onInventoryEvent(InventoryMoveItemEvent event) + { + Inventory source = event.getSource(); + if (source.getHolder() instanceof Player) + { + refreshClient(((Player) source.getHolder())); + } + + Inventory dest = event.getDestination(); + if (dest.getHolder() instanceof Player) + { + refreshClient(((Player) dest.getHolder())); + } + } + + @EventHandler + public void onRespawn(PlayerRespawnEvent event) + { + refreshClient(event.getPlayer()); + } + + @EventHandler + public void particle(UpdateEvent event) + { + if (event.getType() == UpdateType.SLOW) + { + for (Player player : UtilServer.getPlayers()) + { + refreshClient(player); + } + } + + if (event.getType() == UpdateType.SEC) + { + for (Player player : UtilServer.getPlayers()) + { + int inventoryValue = getInventoryValue(player); + + if (isWeakling(player)) + { + for (Player other : UtilServer.getPlayers()) + { + if (canMurderOccur(other, player, other.getLocation()) && inventoryValue <= 2000) + { + UtilParticle.PlayParticle(UtilParticle.ParticleType.ANGRY_VILLAGER, player.getEyeLocation().add(0, 0.25, 0), 0, 0, 0, 0, 1, UtilParticle.ViewDist.NORMAL, other); + } + } + } + } + } + } + + public boolean isWeakling(Player player) + { + return Get(player).isWeakling(); + } + + public int getInventoryValue(Player player) + { + return Get(player).getInventoryValue(); + } + + private int calculateInventoryValue(Player player) + { + int value = 0; + + // +4 for armor contents + for (int i = 0; i < player.getInventory().getSize() + 4; i++) + { + ItemStack stack = player.getInventory().getItem(i); + + if (stack == null) + { + continue; + } + + ClansShopItem item = ClansShopItem.getByItem(stack.getType(), stack.getDurability()); + + if (item != null) + { + value += item.getSellPrice(stack.getAmount()); + } + } + + return value; + } + + private boolean canMurderOccur(Player killer, Player victim, Location location) + { + if (killer.equals(victim)) return false; + if (isWeakling(killer)) return false; + if (victim.isDead()) return false; + if (_clansManager.getClanUtility().getClaim(location) != null) return false; + + return true; + } + + private void refreshClient(Player player) + { + boolean weakling = true; + PlayerInventory inventory = player.getInventory(); + + // Add 4 for armor contents + int inventorySize = inventory.getSize() + 4; + for (int i = 0; i < inventorySize; i++) + { + Material type = inventory.getItem(i) != null ? inventory.getItem(i).getType() : null; + + weakling = !(weapons.contains(type) || armor.contains(type)); + + if (!weakling) break; + } + + Get(player).setIsWeakling(weakling); + Get(player).setInventoryValue(calculateInventoryValue(player)); + } + + @Override + protected ClientMurder addPlayer(UUID uuid) + { + return new ClientMurder(); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/ClansBlacklist.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/ClansBlacklist.java new file mode 100644 index 00000000..72fad982 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/ClansBlacklist.java @@ -0,0 +1,78 @@ +package mineplex.game.clans.clans.nameblacklist; + +import java.util.List; + +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.nameblacklist.commands.AddBlacklistCommand; +import mineplex.game.clans.clans.nameblacklist.repository.ClanNameBlacklistRepository; + +public class ClansBlacklist extends MiniPlugin +{ + public enum Perm implements Permission + { + BLACKLIST_COMMAND, + } + + private List _blacklist; + private ClanNameBlacklistRepository _repository; + + public ClansBlacklist(JavaPlugin plugin) + { + super("Clan Name Blacklist", plugin); + + _repository = new ClanNameBlacklistRepository(plugin, this); + + runAsync(() -> _repository.loadNames(this::setBlacklist)); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.CMOD.setPermission(Perm.BLACKLIST_COMMAND, false, true); + PermissionGroup.ADMIN.setPermission(Perm.BLACKLIST_COMMAND, true, true); + } + + // Fetch new blacklisted clans every 16 seconds (in case someone blacklists a clan name on a different server) + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.SLOWER) + { + runAsync(() -> _repository.loadNames(this::setBlacklist)); + } + } + + private void setBlacklist(List blacklist) + { + _blacklist = blacklist; + } + + public boolean allowed(String name) + { + return !_blacklist.contains(name.toLowerCase()); + } + + public void add(String name) + { + _blacklist.add(name); + } + + public void addCommands() + { + addCommand(new AddBlacklistCommand(this)); + } + + public ClanNameBlacklistRepository getRepository() + { + return _repository; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/commands/AddBlacklistCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/commands/AddBlacklistCommand.java new file mode 100644 index 00000000..d0c8e0c6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/commands/AddBlacklistCommand.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.clans.nameblacklist.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.game.clans.clans.nameblacklist.ClansBlacklist; + +public class AddBlacklistCommand extends CommandBase +{ + public AddBlacklistCommand(ClansBlacklist plugin) + { + super(plugin, ClansBlacklist.Perm.BLACKLIST_COMMAND, "blacklistname"); + } + + @Override + public void Execute(final Player caller, String[] args) + { + if (args == null || args.length < 1) + { + UtilPlayer.message(caller, C.cGold + "/blacklistname - Blacklists a clan name."); + } + else if (args.length >= 1) + { + final String blacklist = args[0]; + + Plugin.runAsync(() -> + { + Plugin.getRepository().add(blacklist, caller.getName()); + UtilPlayer.message(caller, F.main("Clans", "Successfully added " + F.elem(blacklist) + " to the clan name blacklist.")); + if (!UtilServer.isTestServer()) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", + new SlackMessage("Clans Command Logger", "crossed_swords", caller.getName() + " has blacklisted the clan name " + blacklist + "."), + true); + } + }); + } + else + { + UtilPlayer.message(caller, C.cGold + "/blacklistname - Blacklists a clan name."); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/repository/ClanNameBlacklistRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/repository/ClanNameBlacklistRepository.java new file mode 100644 index 00000000..f9924092 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nameblacklist/repository/ClanNameBlacklistRepository.java @@ -0,0 +1,70 @@ +package mineplex.game.clans.clans.nameblacklist.repository; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.Callback; +import mineplex.game.clans.clans.nameblacklist.ClansBlacklist; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnTimestamp; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class ClanNameBlacklistRepository extends RepositoryBase +{ + private static final String CREATE = "CREATE TABLE IF NOT EXISTS clanNameBlacklist (" + + "clanName VARCHAR(20) NOT NULL, " + + "admin VARCHAR(16) NOT NULL, " + + "added TIMESTAMP," + + "PRIMARY KEY (clanName));"; + + private static final String GET = "SELECT * FROM clanNameBlacklist;"; + private static final String ADD = "INSERT INTO clanNameBlacklist (clanName, admin, added) VALUES (?, ?, ?);"; + private static final String REMOVE = "DELETE FROM clanNameBlacklist WHERE clanName=?;"; + + private ClansBlacklist _blacklist; + + public ClanNameBlacklistRepository(JavaPlugin plugin, ClansBlacklist blacklist) + { + super(DBPool.getAccount()); + + _blacklist = blacklist; + } + + public void add(String name, String mod) + { + _blacklist.add(name.toLowerCase()); + executeInsert(ADD, null, + new ColumnVarChar("clanName", 20, name.toLowerCase()), + new ColumnVarChar("admin", 16, mod), + new ColumnTimestamp("added", new Timestamp(System.currentTimeMillis())) + ); + } + + public void loadNames(final Callback> callback) + { + executeQuery(GET, resultSet -> + { + final List list = new ArrayList<>(); + + while (resultSet.next()) + { + String clanName = resultSet.getString("clanName"); + String mod = resultSet.getString("admin"); + + list.add(clanName); + } + + callback.run(list); + }); + } + + @Override + protected void update() + { + executeUpdate(CREATE); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java new file mode 100644 index 00000000..f45f1850 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/BossNetherPortal.java @@ -0,0 +1,312 @@ +package mineplex.game.clans.clans.nether; + +import java.util.LinkedList; +import java.util.List; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.spawn.Spawn; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.potion.PotionEffectType; + +import com.google.common.collect.Lists; + +/** + * Data and listener class for individual nether portals opened by bosses + */ +public class BossNetherPortal implements Listener +{ + private static final int SECONDS_UNTIL_PORTAL = 5; + private List _frame = Lists.newArrayList(); + private List _portal = Lists.newArrayList(); + private Location _loc; + private Location[] _corners; + private boolean _returnPortal; + private byte _portalFacing; + private LinkedList _closeWarnings = new LinkedList<>(); + + public boolean Open = false; + public long Expire = -1; + + public BossNetherPortal(Location firstCorner, Location secondCorner, boolean returnPortal) + { + int maxX = Math.max(firstCorner.getBlockX(), secondCorner.getBlockX()); + int minX = Math.min(firstCorner.getBlockX(), secondCorner.getBlockX()); + int maxY = Math.max(firstCorner.getBlockY(), secondCorner.getBlockY()); + int minY = Math.min(firstCorner.getBlockY(), secondCorner.getBlockY()); + int maxZ = Math.max(firstCorner.getBlockZ(), secondCorner.getBlockZ()); + int minZ = Math.min(firstCorner.getBlockZ(), secondCorner.getBlockZ()); + + for (int x = minX; x <= maxX; x++) + { + for (int y = minY; y <= maxY; y++) + { + for (int z = minZ; z <= maxZ; z++) + { + if (minX == maxX) + { + if ((y != minY && y != maxY) && (z != minZ && z != maxZ)) + { + _portal.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + else + { + _frame.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + } + else + { + if ((x != minX && x != maxX) && (y != minY && y != maxY)) + { + _portal.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + else + { + _frame.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + } + } + } + } + + _loc = new Location(firstCorner.getWorld(), minX + ((maxX - minX) / 2), maxY, minZ + ((maxZ - minZ) / 2)); + _corners = new Location[] {firstCorner, secondCorner}; + _returnPortal = returnPortal; + + if (maxX == minX) + { + _portalFacing = (byte)2; + } + else + { + _portalFacing = (byte)0; + } + } + + private boolean isInPortal(Block block) + { + return _frame.contains(block) || _portal.contains(block); + } + + /** + * Gets the center location of this portal + * @return The center location of this portal + */ + public Location getLocation() + { + return _loc; + } + + /** + * Gets the corners of this portal + * @return An array of the corners of this portal + */ + public Location[] getCorners() + { + return _corners; + } + + /** + * Checks if this portal is a return portal + * @return Whether this portal is a return portal + */ + public boolean isReturnPortal() + { + return _returnPortal; + } + + /** + * Opens this portal for a given duration + * @param duration The duration to hold the portal open for + */ + @SuppressWarnings("deprecation") + public void open(long duration) + { + if (Open) + { + if (Expire != -1) + { + Expire = Expire + duration; + } + } + else + { + if (!_returnPortal) + { + Expire = System.currentTimeMillis() + duration; + } + Open = true; + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + for (Block block : _frame) + { + block.setType(Material.OBSIDIAN); + } + for (Block block : _portal) + { + block.setType(Material.PORTAL); + block.setData(_portalFacing); + } + _closeWarnings.add(UtilTime.convert(5, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + _closeWarnings.add(UtilTime.convert(1, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + _closeWarnings.add(30000L); + _closeWarnings.add(10000L); + _closeWarnings.add(5000L); + _closeWarnings.add(4000L); + _closeWarnings.add(3000L); + _closeWarnings.add(2000L); + _closeWarnings.add(1000L); + } + } + + /** + * Closes this portal and clears away its blocks + */ + public void close() + { + Open = false; + Expire = -1; + for (Block block : _portal) + { + block.setType(Material.AIR); + } + for (Block block : _frame) + { + block.setType(Material.AIR); + } + HandlerList.unregisterAll(this); + _closeWarnings.clear(); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBreak(BlockDamageEvent event) + { + if (isInPortal(event.getBlock())) + { + event.setInstaBreak(false); + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy a " + F.clansNether("Nether Portal"))); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void playerPortalEvent(PlayerPortalEvent event) + { + if (isInPortal(event.getFrom().getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void entityPortalEvent(EntityPortalEvent event) + { + if (isInPortal(event.getFrom().getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onEnterPortal(EntityPortalEnterEvent event) + { + if (event.getEntity() instanceof Player) + { + if (isInPortal(event.getLocation().getBlock())) + { + Bukkit.getScheduler().runTaskLater(ClansManager.getInstance().getPlugin(), () -> + { + if (isInPortal(event.getEntity().getLocation().getBlock())) + { + if (isReturnPortal()) + { + ClansManager.getInstance().getNetherManager().InNether.remove((Player)event.getEntity()); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getReturnLocation((Player)event.getEntity())); + ClansManager.getInstance().getNetherManager().OverworldOrigins.remove((Player)event.getEntity()); + ((Player)event.getEntity()).removePotionEffect(PotionEffectType.NIGHT_VISION); + UtilPlayer.message(event.getEntity(), F.main(ClansManager.getInstance().getNetherManager().getName(), "You have escaped " + F.clansNether("The Nether") + "!")); + ClansManager.getInstance().getCombatManager().getLog((Player)event.getEntity()).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + } + else + { + ClansManager.getInstance().getNetherManager().InNether.put((Player)event.getEntity(), Expire); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getNetherWorld().getSpawnLocation()); + ClansManager.getInstance().getCombatManager().getLog((Player)event.getEntity()).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + ClansManager.getInstance().ClanTips.displayTip(TipType.ENTER_NETHER, (Player)event.getEntity()); + } + } + }, SECONDS_UNTIL_PORTAL * 20); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockPhysics(BlockPhysicsEvent event) + { + if (isInPortal(event.getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void handleExpiration(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (Open && Expire != -1) + { + Long warning = -1L; + for (Long test : _closeWarnings) + { + if ((Expire - System.currentTimeMillis()) < warning) + { + warning = test; + break; + } + } + if (warning != -1) + { + _closeWarnings.remove(warning); + Bukkit.broadcastMessage(F.main(ClansManager.getInstance().getNetherManager().getName(), "The " + F.clansNether("Nether Portal") + " at " + F.elem(UtilWorld.locToStrClean(getLocation())) + " will close in " + F.elem(UtilTime.MakeStr(warning)) + "!")); + } + } + if (Open && Expire != -1 && System.currentTimeMillis() >= Expire) + { + close(); + ClansManager.getInstance().getNetherManager().BossPortals.remove(this); + } + } + + @EventHandler + public void onUnload(ChunkUnloadEvent event) + { + if (event.getChunk().getX() == _loc.getChunk().getX() && event.getChunk().getZ() == _loc.getChunk().getZ()) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java new file mode 100644 index 00000000..6c9ab28c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java @@ -0,0 +1,610 @@ +package mineplex.game.clans.clans.nether; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.WorldBorder; +import org.bukkit.WorldCreator; +import org.bukkit.block.Block; +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.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.google.common.collect.Lists; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.generator.VoidGenerator; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +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.common.util.UtilTime.TimeUnit; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.clans.nether.command.ForceTeleportCommand; +import mineplex.game.clans.clans.nether.command.PortalCommand; +import mineplex.game.clans.clans.nether.data.ClaimData; +import mineplex.game.clans.clans.nether.miniboss.NetherMinibossManager; +import mineplex.game.clans.clans.worldevent.boss.BossDeathEvent; +import mineplex.game.clans.spawn.Spawn; + +/** + * Manager for all nether features + */ +public class NetherManager extends MiniPlugin +{ + public enum Perm implements Permission + { + PORTAL_COMMAND, + PORTAL_CLOSE_COMMAND, + PORTAL_CREATE_COMMAND, + PORTAL_DELETE_COMMAND, + PORTAL_FORCE_COMMAND, + PORTAL_LIST_COMMAND, + PORTAL_OPEN_COMMAND, + } + + private static final long PORTAL_OPEN_DURATION = UtilTime.convert(10, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); + private static final String CLAIM_WAND_NAME = C.cRedB + "Portal Claim Wand"; + private static final String[] CLAIM_WAND_LORE = new String[] {C.cYellow + "Left Click to select the Portal's first corner", C.cYellow + "Right Click to select the Portal's second corner"}; + private static final ItemStack CLAIM_WAND = new ItemBuilder(Material.WOOD_AXE).setTitle(CLAIM_WAND_NAME).setLore(CLAIM_WAND_LORE).build(); + private static final int SPAWN_MIN_X = 30; + private static final int SPAWN_MIN_Z = 99; + private static final int SPAWN_MAX_X = 56; + private static final int SPAWN_MAX_Z = 115; + + private PortalRepository _repo; + private NetherMinibossManager _miniboss; + private World _netherWorld; + private List _portals = new ArrayList<>(); + public List BossPortals = new ArrayList<>(); + private List _returnPortals = new ArrayList<>(); + public Map InNether = new HashMap<>(); + public Map OverworldOrigins = new HashMap<>(); + public Map Claiming = new HashMap<>(); + + public NetherManager(ClansManager manager) + { + super("Nether", manager.getPlugin()); + + begin(); + _miniboss = new NetherMinibossManager(this); + addCommand(new PortalCommand(this)); + addCommand(new ForceTeleportCommand(this)); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_CLOSE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_CREATE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_DELETE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_FORCE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_LIST_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.PORTAL_OPEN_COMMAND, true, true); + } + + private void begin() + { + if (Bukkit.getWorld("nether") == null) + { + WorldCreator creator = new WorldCreator("nether"); + creator.generator(new VoidGenerator()); + Bukkit.createWorld(creator); + } + _netherWorld = Bukkit.getWorld("nether"); + _netherWorld.setSpawnLocation(43, 135, 113); + WorldBorder worldBorder = _netherWorld.getWorldBorder(); + worldBorder.setCenter(0, 0); + worldBorder.setSize(800 * 2); + + _repo = new PortalRepository(getPlugin(), this); + loadPortals(); + } + + private void loadPortals() + { + _repo.loadPortals(); + } + + @Override + public void disable() + { + closePortals(); + for (Player player : InNether.keySet()) + { + player.teleport(Spawn.getNorthSpawn()); + } + InNether.clear(); + } + + /** + * Get the manager for nether miniboss + * @return The loaded Nether Miniboss manager + */ + public NetherMinibossManager getMinibossManager() + { + return _miniboss; + } + + /** + * Gets the Nether world + * @return The Nether world + */ + public World getNetherWorld() + { + return _netherWorld; + } + + /** + * Checks if a player is in the nether + * @param player The player to check + * @return Whether the player is in the nether + */ + public boolean isInNether(Player player) + { + return isInNether(player.getLocation()); + } + + /** + * Checks if a location is in the nether + * @param location The location to check + * @return Whether the player is in the nether + */ + public boolean isInNether(Location location) + { + return location.getWorld().equals(_netherWorld); + } + + /** + * Checks if a location is inside Nether Spawn + * @param loc The location to check + * @return true if the location is inside the Nether Spawn + */ + public boolean isInSpawn(Location loc) + { + if (loc.getWorld().equals(getNetherWorld())) + { + if (loc.getBlockX() >= SPAWN_MIN_X && loc.getBlockX() <= SPAWN_MAX_X) + { + if (loc.getBlockZ() >= SPAWN_MIN_Z && loc.getBlockZ() <= SPAWN_MAX_Z) + { + return true; + } + } + } + return false; + } + + /** + * Gets the place a player will exit the nether + * @param player The player to check + * @return The place the player will exit the nether + */ + public Location getReturnLocation(Player player) + { + Location defaultLoc = Spawn.getWestTown(); + if (UtilMath.random.nextDouble() <= .5) + { + defaultLoc = Spawn.getEastTown(); + } + return OverworldOrigins.getOrDefault(player, defaultLoc); + } + + /** + * Fetches the nether portal with the given id + * @param id The id of the portal + * @return The nether portal with the given id + */ + public NetherPortal getPortal(int id) + { + for (NetherPortal portal : _portals) + { + if (portal.getId() == id) + { + return portal; + } + } + + return null; + } + + public List getReturnPortals() + { + return _returnPortals; + } + + /** + * Loads a nether portal into the manager + * @param portal The portal to load + */ + public void addPortal(NetherPortal portal) + { + _portals.add(portal); + if (portal.isReturnPortal()) + { + _returnPortals.add(portal); + } + _portals.sort(new Comparator() + { + public int compare(NetherPortal o1, NetherPortal o2) + { + if (o1.getId() > o2.getId()) + { + return 1; + } + return -1; + } + }); + } + + /** + * Deletes a nether portal and removes it from the database + * @param portal The portal to remove + */ + public void deletePortal(NetherPortal portal) + { + portal.close(); + _portals.remove(portal); + _returnPortals.remove(portal); + _repo.deletePortal(portal.getId()); + } + + /** + * Spawns a nether portal for a given duration + * @param duration The duration to maintain the portal for + */ + public void spawnPortal(long duration) + { + if (_portals.isEmpty() || _returnPortals.isEmpty()) + { + return; + } + List available = Lists.newArrayList(); + available.addAll(_portals); + for (NetherPortal remove : _returnPortals) + { + available.remove(remove); + } + if (available.isEmpty()) + { + return; + } + NetherPortal portal = available.get(UtilMath.r(available.size())); + portal.open(duration); + for (NetherPortal returnPortal : _returnPortals) + { + returnPortal.open(-1); + } + UtilTextMiddle.display(F.clansNether("Nether Portal"), "Has opened at " + F.elem(UtilWorld.locToStrClean(portal.getLocation()))); + Bukkit.broadcastMessage(F.main(getName(), "A " + F.clansNether("Nether Portal") + " has opened at " + F.elem(UtilWorld.locToStrClean(portal.getLocation())) + " for " + F.elem(UtilTime.MakeStr(duration)) + "!")); + } + + /** + * Spawns a portal for the default remain duration + */ + public void spawnPortal() + { + spawnPortal(PORTAL_OPEN_DURATION); + } + + /** + * Spawns a nether portal when a boss dies + * @param bossSpawn The location where the boss spawned in + */ + public void spawnBossPortal(Location bossSpawn) + { + if (_returnPortals.isEmpty()) + { + return; + } + BossNetherPortal portal = new BossNetherPortal(bossSpawn.clone().add(-2, 5, 0), bossSpawn.clone().add(2, 0, 0), false); + portal.open(PORTAL_OPEN_DURATION); + BossPortals.add(portal); + for (NetherPortal returnPortal : _returnPortals) + { + returnPortal.open(-1); + } + UtilTextMiddle.display(F.clansNether("Nether Portal"), "Has opened at " + F.elem(UtilWorld.locToStrClean(portal.getLocation()))); + Bukkit.broadcastMessage(F.main(getName(), "A " + F.clansNether("Nether Portal") + " has opened at " + F.elem(UtilWorld.locToStrClean(portal.getLocation())) + " for " + F.elem(UtilTime.MakeStr(PORTAL_OPEN_DURATION)) + "!")); + } + + /** + * Creates a portal with the player's stored corners + * @param creator The creator of the portal + * @param returnPortal Whether the portal is a return portal + */ + public void createPortal(Player creator, boolean returnPortal) + { + if (Claiming.getOrDefault(creator, new ClaimData()).getTotalSelected() < 2) + { + UtilPlayer.message(creator, F.main(getName(), "You do not have a top and bottom corner selected!")); + return; + } + + ClaimData data = Claiming.remove(creator); + _repo.addPortal(UtilWorld.locToStr(data.getFirstCorner().getLocation()), UtilWorld.locToStr(data.getSecondCorner().getLocation()), returnPortal); + UtilPlayer.message(creator, F.main(getName(), "Portal successfully created!")); + } + + /** + * Closes all portals and clears away their blocks + */ + public void closePortals() + { + for (NetherPortal portal : _portals) + { + portal.close(); + } + for (BossNetherPortal portal : BossPortals) + { + portal.close(); + } + BossPortals.clear(); + } + + /** + * Displays a list of all portals to a player + * @param player The player to display the list to + */ + public void showPortalList(Player player) + { + UtilPlayer.message(player, F.main(getName(), "Portal List:")); + for (NetherPortal portal : _portals) + { + UtilPlayer.message(player, C.cBlue + "- " + F.elem("Portal " + portal.getId() + ": " + C.cGray + UtilWorld.locToStrClean(portal.getLocation()).replace("(", "").replace(")", ""))); + } + } + + /** + * Gives a player a portal claim wand + * @param player The player to give the wand to + */ + public void giveWand(Player player) + { + player.getInventory().addItem(CLAIM_WAND.clone()); + UtilPlayer.message(player, F.main(getName(), "You have been given a Portal Claim Wand!")); + } + + @EventHandler + public void breakBlock(BlockBreakEvent event) + { + Block block = event.getBlock(); + Player player = event.getPlayer(); + + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + + if (!block.getWorld().equals(_netherWorld)) + { + return; + } + + event.setCancelled(true); + UtilPlayer.message(player, F.main(getName(), "You cannot build in " + F.clansNether("The Nether") + "!")); + } + + @EventHandler + public void placeBlock(BlockPlaceEvent event) + { + Block block = event.getBlock(); + Player player = event.getPlayer(); + + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + + if (!block.getWorld().equals(_netherWorld)) + { + return; + } + + event.setCancelled(true); + UtilPlayer.message(player, F.main(getName(), "You cannot build in " + F.clansNether("The Nether") + "!")); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPortal(PlayerPortalEvent event) + { + if (event.getTo() == null || event.getTo().getWorld().equals(_netherWorld)) + { + return; + } + event.setCancelled(true); + runSyncLater(() -> + { + InNether.remove(event.getPlayer()); + event.getPlayer().teleport(getReturnLocation(event.getPlayer())); + OverworldOrigins.remove(event.getPlayer()); + event.getPlayer().removePotionEffect(PotionEffectType.NIGHT_VISION); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have escaped " + F.clansNether("The Nether") + "!")); + ClansManager.getInstance().getCombatManager().getLog(event.getPlayer()).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + }, 1); + } + + @EventHandler + public void onPortal(EntityPortalEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.FAST) + { + List netherKeys = Lists.newArrayList(); + netherKeys.addAll(InNether.keySet()); + for (Player player : netherKeys) + { + if (System.currentTimeMillis() >= InNether.get(player)) + { + InNether.remove(player); + if (isInNether(player)) + { + player.teleport(getReturnLocation(player)); + OverworldOrigins.remove(player); + player.removePotionEffect(PotionEffectType.NIGHT_VISION); + ClansManager.getInstance().getCombatManager().getLog(player).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + UtilPlayer.message(player, F.main(getName(), "You have been forced to escape " + F.clansNether("The Nether") + " to survive its demonic poisons!")); + } + } + else + { + if (!player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) + { + int ticks = (int)((InNether.get(player) - System.currentTimeMillis()) / 1000) * 20; + player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, ticks, 0)); + } + } + } + + UtilServer.getPlayersCollection() + .stream() + .filter(player -> isInNether(player)) + .forEach(player -> ClansManager.getInstance().getItemMapManager().removeMap(player)); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onQuit(PlayerQuitEvent event) + { + if (isInNether(event.getPlayer())) + { + InNether.remove(event.getPlayer()); + event.getPlayer().teleport(getReturnLocation(event.getPlayer())); + OverworldOrigins.remove(event.getPlayer()); + event.getPlayer().removePotionEffect(PotionEffectType.NIGHT_VISION); + } + Claiming.remove(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onDie(PlayerDeathEvent event) + { + InNether.remove(event.getEntity()); + OverworldOrigins.remove(event.getEntity()); + Claiming.remove(event.getEntity()); + } + + @EventHandler + public void onTpHome(ClansCommandExecutedEvent event) + { + if (!isInNether(event.getPlayer())) + { + return; + } + if (event.getCommand().equalsIgnoreCase("tphome") || event.getCommand().equalsIgnoreCase("stuck")) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot teleport while in " + F.clansNether("The Nether") + "!")); + } + if (event.getCommand().equalsIgnoreCase("claim") || event.getCommand().equalsIgnoreCase("unclaim") || event.getCommand().equalsIgnoreCase("unclaimall") || event.getCommand().equalsIgnoreCase("homeset")) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot manage your clan's territory while in " + F.clansNether("The Nether") + "!")); + } + } + + @EventHandler + public void onDropWand(PlayerDropItemEvent event) + { + ItemStack item = event.getItemDrop().getItemStack(); + if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equalsIgnoreCase(CLAIM_WAND_NAME)) + { + runSyncLater(() -> + { + event.getItemDrop().remove(); + }, 1L); + } + } + + @EventHandler + public void onUseWand(PlayerInteractEvent event) + { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.LEFT_CLICK_BLOCK) + { + return; + } + if (!event.hasBlock() || !event.hasItem()) + { + return; + } + if (!ClansManager.getInstance().getClientManager().Get(event.getPlayer()).hasPermission(Perm.PORTAL_CREATE_COMMAND)) + { + return; + } + ItemStack item = event.getItem(); + if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equalsIgnoreCase(CLAIM_WAND_NAME)) + { + Block block = event.getClickedBlock(); + if (!Claiming.containsKey(event.getPlayer())) + { + Claiming.put(event.getPlayer(), new ClaimData()); + } + ClaimData data = Claiming.get(event.getPlayer()); + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) + { + data.setSecondCorner(block); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have selected the Portal's second corner!")); + } + else + { + data.setFirstCorner(block); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have selected the Portal's first corner!")); + } + event.setCancelled(true); + } + } + + @EventHandler + public void onBossDeath(BossDeathEvent event) + { + spawnBossPortal(event.getEvent().getCenterLocation().clone()); + } + + @EventHandler + public void onBlockDamage(EntityExplodeEvent event) + { + if (isInNether(event.getLocation())) + { + event.setYield(0f); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java new file mode 100644 index 00000000..37adbc2e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherPortal.java @@ -0,0 +1,322 @@ +package mineplex.game.clans.clans.nether; + +import java.util.LinkedList; +import java.util.List; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.spawn.Spawn; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.potion.PotionEffectType; + +import com.google.common.collect.Lists; + +/** + * Data and listener class for individual nether portals + */ +public class NetherPortal implements Listener +{ + private static final int SECONDS_UNTIL_PORTAL = 5; + private int _id; + private List _frame = Lists.newArrayList(); + private List _portal = Lists.newArrayList(); + private Location _loc; + private Location[] _corners; + private boolean _returnPortal; + private byte _portalFacing; + private LinkedList _closeWarnings = new LinkedList<>(); + + public boolean Open = false; + public long Expire = -1; + + public NetherPortal(int id, Location firstCorner, Location secondCorner, boolean returnPortal) + { + _id = id; + int maxX = Math.max(firstCorner.getBlockX(), secondCorner.getBlockX()); + int minX = Math.min(firstCorner.getBlockX(), secondCorner.getBlockX()); + int maxY = Math.max(firstCorner.getBlockY(), secondCorner.getBlockY()); + int minY = Math.min(firstCorner.getBlockY(), secondCorner.getBlockY()); + int maxZ = Math.max(firstCorner.getBlockZ(), secondCorner.getBlockZ()); + int minZ = Math.min(firstCorner.getBlockZ(), secondCorner.getBlockZ()); + + for (int x = minX; x <= maxX; x++) + { + for (int y = minY; y <= maxY; y++) + { + for (int z = minZ; z <= maxZ; z++) + { + if (minX == maxX) + { + if ((y != minY && y != maxY) && (z != minZ && z != maxZ)) + { + _portal.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + else + { + _frame.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + } + else + { + if ((x != minX && x != maxX) && (y != minY && y != maxY)) + { + _portal.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + else + { + _frame.add(firstCorner.getWorld().getBlockAt(x, y, z)); + } + } + } + } + } + + _loc = new Location(firstCorner.getWorld(), minX + ((maxX - minX) / 2), maxY, minZ + ((maxZ - minZ) / 2)); + _corners = new Location[] {firstCorner, secondCorner}; + _returnPortal = returnPortal; + + if (maxX == minX) + { + _portalFacing = (byte)2; + } + else + { + _portalFacing = (byte)0; + } + } + + private boolean isInPortal(Block block) + { + return _frame.contains(block) || _portal.contains(block); + } + + /** + * Gets the id of this portal + * @return This portal's id + */ + public int getId() + { + return _id; + } + + /** + * Gets the center location of this portal + * @return The center location of this portal + */ + public Location getLocation() + { + return _loc; + } + + /** + * Gets the corners of this portal + * @return An array of the corners of this portal + */ + public Location[] getCorners() + { + return _corners; + } + + /** + * Checks if this portal is a return portal + * @return Whether this portal is a return portal + */ + public boolean isReturnPortal() + { + return _returnPortal; + } + + /** + * Opens this portal for a given duration + * @param duration The duration to hold the portal open for + */ + @SuppressWarnings("deprecation") + public void open(long duration) + { + if (Open) + { + if (Expire != -1) + { + Expire = Expire + duration; + } + } + else + { + if (!_returnPortal) + { + Expire = System.currentTimeMillis() + duration; + } + Open = true; + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + for (Block block : _frame) + { + block.setType(Material.OBSIDIAN); + } + for (Block block : _portal) + { + block.setType(Material.PORTAL); + block.setData(_portalFacing); + } + _closeWarnings.add(UtilTime.convert(5, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + _closeWarnings.add(UtilTime.convert(1, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + _closeWarnings.add(30000L); + _closeWarnings.add(10000L); + _closeWarnings.add(5000L); + _closeWarnings.add(4000L); + _closeWarnings.add(3000L); + _closeWarnings.add(2000L); + _closeWarnings.add(1000L); + } + } + + /** + * Closes this portal and clears away its blocks + */ + public void close() + { + Open = false; + Expire = -1; + for (Block block : _portal) + { + block.setType(Material.AIR); + } + for (Block block : _frame) + { + block.setType(Material.AIR); + } + HandlerList.unregisterAll(this); + _closeWarnings.clear(); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBreak(BlockDamageEvent event) + { + if (isInPortal(event.getBlock())) + { + event.setInstaBreak(false); + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy a " + F.clansNether("Nether Portal"))); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void playerPortalEvent(PlayerPortalEvent event) + { + if (isInPortal(event.getFrom().getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void entityPortalEvent(EntityPortalEvent event) + { + if (isInPortal(event.getFrom().getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onEnterPortal(EntityPortalEnterEvent event) + { + if (event.getEntity() instanceof Player) + { + if (isInPortal(event.getLocation().getBlock())) + { + Bukkit.getScheduler().runTaskLater(ClansManager.getInstance().getPlugin(), () -> + { + if (isInPortal(event.getEntity().getLocation().getBlock())) + { + if (isReturnPortal()) + { + ClansManager.getInstance().getNetherManager().InNether.remove((Player)event.getEntity()); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getReturnLocation((Player)event.getEntity())); + ClansManager.getInstance().getNetherManager().OverworldOrigins.remove((Player)event.getEntity()); + ((Player)event.getEntity()).removePotionEffect(PotionEffectType.NIGHT_VISION); + UtilPlayer.message(event.getEntity(), F.main(ClansManager.getInstance().getNetherManager().getName(), "You have escaped " + F.clansNether("The Nether") + "!")); + ClansManager.getInstance().getCombatManager().getLog((Player)event.getEntity()).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + } + else + { + ClansManager.getInstance().getNetherManager().InNether.put((Player)event.getEntity(), Expire); + event.getEntity().teleport(ClansManager.getInstance().getNetherManager().getNetherWorld().getSpawnLocation()); + ClansManager.getInstance().getCombatManager().getLog((Player)event.getEntity()).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + ClansManager.getInstance().ClanTips.displayTip(TipType.ENTER_NETHER, (Player)event.getEntity()); + } + } + }, SECONDS_UNTIL_PORTAL * 20); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockPhysics(BlockPhysicsEvent event) + { + if (isInPortal(event.getBlock())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void handleExpiration(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (Open && Expire != -1) + { + Long warning = -1L; + for (Long test : _closeWarnings) + { + if ((Expire - System.currentTimeMillis()) < test) + { + warning = test; + break; + } + } + if (warning != -1) + { + _closeWarnings.remove(warning); + Bukkit.broadcastMessage(F.main(ClansManager.getInstance().getNetherManager().getName(), "The " + F.clansNether("Nether Portal") + " at " + F.elem(UtilWorld.locToStrClean(getLocation())) + " will close in " + F.elem(UtilTime.MakeStr(warning)) + "!")); + } + } + if (Open && Expire != -1 && System.currentTimeMillis() >= Expire) + { + close(); + } + } + + @EventHandler + public void onUnload(ChunkUnloadEvent event) + { + if (event.getChunk().getX() == _loc.getChunk().getX() && event.getChunk().getZ() == _loc.getChunk().getZ()) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/PortalRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/PortalRepository.java new file mode 100644 index 00000000..789de1e5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/PortalRepository.java @@ -0,0 +1,99 @@ +package mineplex.game.clans.clans.nether; + +import mineplex.core.common.util.UtilWorld; +import mineplex.core.database.MinecraftRepository; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnBoolean; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +import org.bukkit.plugin.java.JavaPlugin; + +/** + * Database repository class for nether portals + */ +public class PortalRepository extends RepositoryBase +{ + private static final String CREATE = "CREATE TABLE IF NOT EXISTS clansNetherPortals (id INT NOT NULL AUTO_INCREMENT," + + "cornerOne VARCHAR(30)," + + "cornerTwo VARCHAR(30)," + + "returnPortal BOOL," + + "PRIMARY KEY (id));"; + + private static final String GET_PORTALS = "SELECT * FROM clansNetherPortals;"; + private static final String INSERT_PORTAL = "INSERT INTO clansNetherPortals (cornerOne, cornerTwo, returnPortal) VALUES (?, ?, ?);"; + private static final String DELETE_PORTAL = "DELETE FROM clansNetherPortals WHERE id=?;"; + + private NetherManager _nether; + + public PortalRepository(JavaPlugin plugin, NetherManager portalManager) + { + super(DBPool.getAccount()); + + _nether = portalManager; + } + + /** + * Loads all stored portals + */ + public void loadPortals() + { + _nether.runAsync(() -> + { + executeQuery(GET_PORTALS, resultSet -> + { + while (resultSet.next()) + { + final int id = resultSet.getInt("id"); + final String cornerOne = resultSet.getString("cornerOne"); + final String cornerTwo = resultSet.getString("cornerTwo"); + final boolean returnPortal = resultSet.getBoolean("returnPortal"); + + _nether.runSync(() -> + { + NetherPortal portal = new NetherPortal(id, UtilWorld.strToLoc(cornerOne), UtilWorld.strToLoc(cornerTwo), returnPortal); + _nether.addPortal(portal); + }); + } + }); + }); + } + + /** + * Adds a portal into the database and loaded portals + * @param cornerOne The serialized first corner of the portal + * @param cornerTwo The serialized second corner of the portal + * @param returnPortal Whether the portal is a return portal + */ + public void addPortal(final String cornerOne, final String cornerTwo, final boolean returnPortal) + { + _nether.runAsync(() -> + { + executeInsert(INSERT_PORTAL, resultSet -> + { + while (resultSet.next()) + { + final int id = resultSet.getInt(1); + _nether.runSync(() -> + { + NetherPortal portal = new NetherPortal(id, UtilWorld.strToLoc(cornerOne), UtilWorld.strToLoc(cornerTwo), returnPortal); + _nether.addPortal(portal); + }); + } + }, new ColumnVarChar("cornerOne", 30, cornerOne), new ColumnVarChar("cornerTwo", 30, cornerTwo), new ColumnBoolean("returnPortal", returnPortal)); + }); + } + + /** + * Deletes the portal with the given id from the database + * @param id The id of the portal to delete + */ + public void deletePortal(final int id) + { + _nether.runAsync(() -> + { + executeUpdate(DELETE_PORTAL, new ColumnInt("id", id)); + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CloseCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CloseCommand.java new file mode 100644 index 00000000..f86df3db --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CloseCommand.java @@ -0,0 +1,26 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.nether.NetherManager; + +/** + * Command to close all nether portals + */ +public class CloseCommand extends CommandBase +{ + public CloseCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_CLOSE_COMMAND, "close"); + } + + @Override + public void Execute(Player caller, String[] args) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Closing all " + F.clansNether("Nether Portals") + "!")); + Plugin.closePortals(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java new file mode 100644 index 00000000..41ca3326 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/CreateCommand.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.nether.NetherManager; + +/** + * Command to create a nether portal + */ +public class CreateCommand extends CommandBase +{ + public CreateCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_CREATE_COMMAND, "create"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Boolean returnPortal = null; + try + { + returnPortal = Boolean.parseBoolean(args[0]); + } + catch (Exception e) {} + + if (returnPortal == null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: " + F.elem("/portal " + _aliasUsed + " "))); + return; + } + + Plugin.createPortal(caller, returnPortal); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java new file mode 100644 index 00000000..13f1ba34 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/DeleteCommand.java @@ -0,0 +1,39 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.nether.NetherManager; +import mineplex.game.clans.clans.nether.NetherPortal; + +/** + * Command to delete a nether portal + */ +public class DeleteCommand extends CommandBase +{ + public DeleteCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_DELETE_COMMAND, "delete", "remove"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Integer id = null; + try + { + id = Integer.parseInt(args[0]); + } + catch (Exception e) {} + if (id == null || Plugin.getPortal(id) == null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: " + F.elem("/portal " + _aliasUsed + " "))); + return; + } + NetherPortal portal = Plugin.getPortal(id); + UtilPlayer.message(caller, F.main(Plugin.getName(), "Deleting the " + F.clansNether("Nether Portal") + " with ID " + id + "!")); + Plugin.deletePortal(portal); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/ForceTeleportCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/ForceTeleportCommand.java new file mode 100644 index 00000000..7c1c3c9e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/ForceTeleportCommand.java @@ -0,0 +1,69 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.nether.NetherManager; +import mineplex.game.clans.spawn.Spawn; + +/** + * Command to artificially portal + */ +public class ForceTeleportCommand extends CommandBase +{ + public ForceTeleportCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_FORCE_COMMAND, "forcePortal"); + } + + @Override + public void Execute(Player caller, String[] args) + { + boolean natural = false; + + if (args.length > 0 && (args[0].equalsIgnoreCase("true") || args[0].equalsIgnoreCase("false"))) + { + natural = Boolean.parseBoolean(args[0]); + } + + if (Plugin.isInNether(caller)) + { + if (natural) + { + Plugin.InNether.remove(caller); + caller.teleport(Plugin.getReturnLocation(caller)); + Plugin.OverworldOrigins.remove(caller); + caller.removePotionEffect(PotionEffectType.NIGHT_VISION); + UtilPlayer.message(caller, F.main(ClansManager.getInstance().getNetherManager().getName(), "You have escaped " + F.clansNether("The Nether") + "!")); + ClansManager.getInstance().runSyncLater(() -> + { + ClansManager.getInstance().getCombatManager().getLog(caller).SetLastCombatEngaged(System.currentTimeMillis()); + }, 20); + } + else + { + caller.teleport(Spawn.getNorthSpawn()); + } + } + else + { + if (natural) + { + Plugin.InNether.put(caller, System.currentTimeMillis() + UtilTime.convert(10, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + caller.teleport(Plugin.getNetherWorld().getSpawnLocation()); + ClansManager.getInstance().ClanTips.displayTip(TipType.ENTER_NETHER, caller); + } + else + { + caller.teleport(Plugin.getNetherWorld().getSpawnLocation()); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/ListCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/ListCommand.java new file mode 100644 index 00000000..a62bbb12 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/ListCommand.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.clans.nether.NetherManager; + +/** + * Command to list all nether portals + */ +public class ListCommand extends CommandBase +{ + public ListCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_LIST_COMMAND, "list"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.showPortalList(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/PortalCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/PortalCommand.java new file mode 100644 index 00000000..d6b13bf6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/PortalCommand.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.MultiCommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.nether.NetherManager; + +/** + * Base portal command + */ +public class PortalCommand extends MultiCommandBase +{ + public PortalCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_COMMAND, "netherportal", "portal"); + + AddCommand(new CreateCommand(plugin)); + AddCommand(new DeleteCommand(plugin)); + AddCommand(new ListCommand(plugin)); + AddCommand(new SpawnCommand(plugin)); + AddCommand(new CloseCommand(plugin)); + AddCommand(new WandCommand(plugin)); + } + + @Override + protected void Help(Player caller, String[] args) + { + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " spawn", "Forces a Nether Portal to spawn", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " close", "Closes all Nether Portals", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " list", "Lists all loaded Nether Portals", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " wand", "Gives you a Nether Portal claim wand", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " create", "Creates a Nether Portal with the corners you have selected", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " delete", "Deletes a loaded Nether Portal", ChatColor.DARK_RED)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/SpawnCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/SpawnCommand.java new file mode 100644 index 00000000..bc5db8ba --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/SpawnCommand.java @@ -0,0 +1,26 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.nether.NetherManager; + +/** + * Command to open a nether portal + */ +public class SpawnCommand extends CommandBase +{ + public SpawnCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_OPEN_COMMAND, "spawn"); + } + + @Override + public void Execute(Player caller, String[] args) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Spawning a " + F.clansNether("Nether Portal" + "!"))); + Plugin.spawnPortal(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/WandCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/WandCommand.java new file mode 100644 index 00000000..537e25b6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/command/WandCommand.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.clans.nether.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.clans.nether.NetherManager; + +/** + * Command to give yourself a portal creation wand + */ +public class WandCommand extends CommandBase +{ + public WandCommand(NetherManager plugin) + { + super(plugin, NetherManager.Perm.PORTAL_CREATE_COMMAND, "wand"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.giveWand(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/data/ClaimData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/data/ClaimData.java new file mode 100644 index 00000000..96570e1b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/data/ClaimData.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.clans.nether.data; + +import org.bukkit.block.Block; + +/** + * Data class to hold specified player portal corners + */ +public class ClaimData +{ + private Block _first, _second; + + /** + * Fetches the first selected corner + * @return The first selected corner + */ + public Block getFirstCorner() + { + return _first; + } + + /** + * Fetches the second selected corner + * @return The second selected corner + */ + public Block getSecondCorner() + { + return _second; + } + + /** + * Fetches the total count of selected corners + * @return The number of selected corners + */ + public int getTotalSelected() + { + int total = 2; + if (_first == null) + { + total--; + } + if (_second == null) + { + total--; + } + + return total; + } + + /** + * Sets the first selected corner + * @param block The block to set the corner to + */ + public void setFirstCorner(Block block) + { + _first = block; + } + + /** + * Sets the first selected corner + * @param block The block to set the corner to + */ + public void setSecondCorner(Block block) + { + _second = block; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/MinibossFireball.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/MinibossFireball.java new file mode 100644 index 00000000..ea297668 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/MinibossFireball.java @@ -0,0 +1,89 @@ +package mineplex.game.clans.clans.nether.miniboss; + +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.LargeFireball; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.game.clans.clans.ClansManager; + +/** + * Manager class for managing boss fireballs + */ +public class MinibossFireball implements Listener +{ + private static final double FIREBALL_EXPLOSION_RANGE = 5; + private static final float SOUND_VOLUME = 1f; + private static final float SOUND_PITCH = 0.8f; + private static final double STRENGTH_MULTIPLIER = 1.6; + private static final double VERT_MULTIPLIER = 0.8; + + public MinibossFireball() + { + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + } + + @EventHandler + public void onHit(ProjectileHitEvent event) + { + Projectile proj = event.getEntity(); + + if (!(proj instanceof LargeFireball)) + { + return; + } + if (!proj.hasMetadata("MINIBOSS_FIREBALL")) + { + return; + } + + Map hitMap = UtilEnt.getInRadius(proj.getLocation(), FIREBALL_EXPLOSION_RANGE); + for (LivingEntity cur : hitMap.keySet()) + { + double range = hitMap.get(cur); + + ClansManager.getInstance().getCondition().Factory().Ignite("Fireball", cur, ((LivingEntity)proj.getMetadata("MINIBOSS_FIREBALL").get(0).value()), 7 * range, false, false); + ClansManager.getInstance().getCondition().Factory().Falling("Fireball", cur, ((LivingEntity)proj.getMetadata("MINIBOSS_FIREBALL").get(0).value()), 10, false, true); + UtilAction.velocity(cur, UtilAlg.getTrajectory(proj.getLocation().add(0, -0.5, 0), cur.getEyeLocation()), + STRENGTH_MULTIPLIER * range, false, 0, VERT_MULTIPLIER * range, 1.2, true); + } + } + + /** + * Checks if the given projectile is a boss fireball + * @param entity The projectile to check + * @return Whether the given projectile is a boss fireball + */ + public static boolean isFireball(Projectile entity) + { + return entity.hasMetadata("MINIBOSS_FIREBALL"); + } + + /** + * Makes an entity shoot a fireball + * @param shooter The entity to shoot from + */ + public static void launchFireball(LivingEntity shooter) + { + LargeFireball ball = shooter.launchProjectile(LargeFireball.class); + ball.setShooter(shooter); + ball.setIsIncendiary(false); + ball.setYield(0); + ball.setBounce(false); + ball.teleport(shooter.getEyeLocation().add(shooter.getLocation().getDirection().multiply(1))); + ball.setVelocity(new Vector(0,0,0)); + ball.setMetadata("MINIBOSS_FIREBALL", new FixedMetadataValue(ClansManager.getInstance().getPlugin(), shooter)); + shooter.getWorld().playSound(shooter.getLocation(), Sound.GHAST_FIREBALL, SOUND_VOLUME, SOUND_PITCH); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java new file mode 100644 index 00000000..4cebeeb6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMiniBoss.java @@ -0,0 +1,128 @@ +package mineplex.game.clans.clans.nether.miniboss; + +import java.util.Arrays; + +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.world.ChunkUnloadEvent; + +/** + * Base class for nether minibosses + * @param The type of entity this boss will use + */ +public abstract class NetherMiniBoss implements Listener +{ + private Mob _entity; + private EntityType _type; + private String _name; + private double _maxHealth; + private Location _spawn; + + public NetherMiniBoss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + _name = displayName; + _maxHealth = maxHealth; + _spawn = spawn; + _type = type; + + spawn(); + } + + @SuppressWarnings("unchecked") + private void spawn() + { + _entity = (Mob) _spawn.getWorld().spawnEntity(_spawn, _type); + _entity.setMaxHealth(_maxHealth); + _entity.setHealth(_maxHealth); + _entity.setCustomName(_name); + _entity.setCustomNameVisible(true); + + customSpawn(); + Bukkit.getPluginManager().registerEvents(this, ClansManager.getInstance().getPlugin()); + } + + /** + * Fetches the entity for this boss + * @return The entity for this boss + */ + public Mob getEntity() + { + return _entity; + } + + /** + * Method called after the entity spawns + */ + public void customSpawn() {}; + + /** + * Method called when the entity dies + * @param deathLocation The location where the entity died + */ + public void customDeath(Location deathLocation) {}; + + /** + * Method called when the entity despawns for non-death reasons + */ + public void customDespawn() {}; + + /** + * Method called for updating every 10 ticks + */ + public void update() {}; + + @EventHandler + public void onDeath(EntityDeathEvent event) + { + if (event.getEntity().equals(_entity)) + { + event.setDroppedExp(0); + event.getDrops().clear(); + HandlerList.unregisterAll(this); + customDeath(event.getEntity().getLocation()); + } + } + + @EventHandler + public void onUnload(ChunkUnloadEvent event) + { + if (Arrays.asList(event.getChunk().getEntities()).contains(_entity)) + { + HandlerList.unregisterAll(this); + _entity.remove(); + customDespawn(); + return; + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (!_entity.isValid()) + { + HandlerList.unregisterAll(this); + customDespawn(); + return; + } + + if (_entity.getFireTicks() > 0) + { + _entity.setFireTicks(-1); + } + update(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java new file mode 100644 index 00000000..d93b5ba0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossManager.java @@ -0,0 +1,135 @@ +package mineplex.game.clans.clans.nether.miniboss; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.world.ChunkUnloadEvent; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.nether.NetherManager; +import mineplex.minecraft.game.classcombat.event.ClassCombatCreatureAllowSpawnEvent; + +/** + * Manager to handle miniboss spawning in the nether + */ +public class NetherMinibossManager implements Listener +{ + private static final long MINIBOSS_SPAWN_RATE = 10000; + private NetherManager _manager; + private Map _spawns = new HashMap<>(); + private long _lastSpawned; + private boolean _allowSpawn = false; + private boolean _allowSpawnEvent = false; + + public NetherMinibossManager(NetherManager manager) + { + _manager = manager; + new MinibossFireball(); + manager.runSyncLater(() -> + { + List sort = Lists.newArrayList(); + sort.add(new Location(manager.getNetherWorld(), -18, 142, 61)); + sort.add(new Location(manager.getNetherWorld(), -39, 133, -25)); + sort.add(new Location(manager.getNetherWorld(), -102, 133, -99)); + sort.add(new Location(manager.getNetherWorld(), -27, 141, -140)); + sort.add(new Location(manager.getNetherWorld(), 32, 143, -95)); + sort.add(new Location(manager.getNetherWorld(), 43, 134, 22)); + sort.add(new Location(manager.getNetherWorld(), 102, 141, -31)); + sort.add(new Location(manager.getNetherWorld(), 151, 136, 34)); + sort.sort((o1, o2) -> + { + if (UtilMath.offset2d(o1, manager.getNetherWorld().getSpawnLocation()) < UtilMath.offset(o2, manager.getNetherWorld().getSpawnLocation())) + { + return -1; + } + return 1; + }); + for (int i = 0; i < 3; i++) + { + _spawns.put(sort.get(i).add(0.5, 1.5, 0.5), NetherMinibossType.ARCHER); + } + for (int i = 3; i < 6; i++) + { + _spawns.put(sort.get(i).add(0.5, 1.5, 0.5), NetherMinibossType.WARRIOR); + } + for (int i = 6; i < 8; i++) + { + _spawns.put(sort.get(i).add(0.5, 1.5, 0.5), NetherMinibossType.GHAST); + } + Bukkit.getPluginManager().registerEvents(this, manager.getPlugin()); + }, 20L); + } + + private void spawnAttacker(Location loc) + { + NetherMinibossType bossType = _spawns.get(loc); + + _allowSpawn = true; + bossType.getNewInstance(loc); + _allowSpawn = false; + } + + @EventHandler + public void onAllowSpawn(ClassCombatCreatureAllowSpawnEvent event) + { + if (event.getWorldName().equalsIgnoreCase(_manager.getNetherWorld().getName())) + { + _allowSpawnEvent = event.getAllowed(); + } + } + + @EventHandler + public void onSpawnNormal(EntitySpawnEvent event) + { + if (event.getEntity() instanceof LivingEntity && _manager.getNetherWorld().equals(event.getLocation().getWorld())) + { + if (!_allowSpawn && !_allowSpawnEvent) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onUnload(ChunkUnloadEvent event) + { + if (_manager.getNetherWorld().equals(event.getWorld())) + { + if (!_manager.InNether.isEmpty()) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onSpawnThreat(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + if (!_manager.InNether.isEmpty() && UtilTime.elapsed(_lastSpawned, MINIBOSS_SPAWN_RATE)) + { + _lastSpawned = System.currentTimeMillis(); + for (Location spawn : _spawns.keySet()) + { + spawnAttacker(spawn); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java new file mode 100644 index 00000000..3c48b761 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/NetherMinibossType.java @@ -0,0 +1,49 @@ +package mineplex.game.clans.clans.nether.miniboss; + +import mineplex.game.clans.clans.nether.miniboss.bosses.ArcherMiniboss; +import mineplex.game.clans.clans.nether.miniboss.bosses.GhastMiniboss; +import mineplex.game.clans.clans.nether.miniboss.bosses.WarriorMiniboss; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +/** + * Enum with all types of nether minibosses + */ +public enum NetherMinibossType +{ + GHAST("Ghast", 25D, EntityType.GHAST, GhastMiniboss.class), + WARRIOR("Undead Warrior", 30D, EntityType.ZOMBIE, WarriorMiniboss.class), + ARCHER("Undead Archer", 25D, EntityType.SKELETON, ArcherMiniboss.class) + ; + + private Class> _code; + private String _name; + private Double _maxHealth; + private EntityType _type; + + private NetherMinibossType(String name, Double maxHealth, EntityType type, Class> code) + { + _name = name; + _maxHealth = maxHealth; + _type = type; + _code = code; + } + + /** + * Creates a new instance of this miniboss at a given location + * @param spawn The location to spawn the boss in + * @return The instance of the miniboss + */ + public NetherMiniBoss getNewInstance(Location spawn) + { + try + { + return _code.getConstructor(String.class, Double.class, Location.class, EntityType.class).newInstance(_name, _maxHealth, spawn, _type); + } + catch (Exception e) + { + return null; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/ArcherMiniboss.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/ArcherMiniboss.java new file mode 100644 index 00000000..b280f339 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/ArcherMiniboss.java @@ -0,0 +1,210 @@ +package mineplex.game.clans.clans.nether.miniboss.bosses; + +import java.util.Random; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.amplifiers.AmplifierManager; +import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +/** + * Class for running an individual Archer miniboss + */ +public class ArcherMiniboss extends NetherMiniBoss +{ + private static final int BARBED_LEVEL = 1; + private static final double RUNE_DROP_CHANCE = .02; + private static final int MAX_VALUABLE_DROPS = 5; + private static final Material[] VALUABLE_DROP_TYPES = new Material[] {Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.LEATHER}; + private static final Material[] SET_DROP_TYPES = new Material[] {Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS}; + private static final double SET_DROP_CHANCE = .02; + + public ArcherMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + super(displayName, maxHealth, spawn, type); + } + + @Override + public void customSpawn() + { + Skeleton entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setItemInHand(new ItemStack(Material.BOW)); + eq.setHelmet(new ItemStack(Material.CHAINMAIL_HELMET)); + eq.setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS)); + eq.setBoots(new ItemStack(Material.CHAINMAIL_BOOTS)); + eq.setItemInHandDropChance(0.f); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void customDeath(Location deathLocation) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(VALUABLE_DROP_TYPES[UtilMath.r(VALUABLE_DROP_TYPES.length)], UtilMath.r(MAX_VALUABLE_DROPS) + 1)); + double runeDropChance = RUNE_DROP_CHANCE; + if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) + { + runeDropChance *= AmplifierManager.AMPLIFIER_RUNE_DROP_MULTIPLIER; + } + if (new Random().nextDouble() <= runeDropChance) + { + RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; + deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); + } + if (new Random().nextDouble() <= SET_DROP_CHANCE) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(SET_DROP_TYPES[UtilMath.r(SET_DROP_TYPES.length)], 1)); + } + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void bowShoot(EntityShootBowEvent event) + { + if (BARBED_LEVEL == 0) + { + return; + } + + if (!(event.getProjectile() instanceof Arrow)) + { + return; + } + + if (event.getEntity().getEntityId() != getEntity().getEntityId()) + { + return; + } + + event.getProjectile().setMetadata("BARBED_ARROW", new FixedMetadataValue(ClansManager.getInstance().getPlugin(), 2)); + } + + @EventHandler(priority = EventPriority.HIGH) + public void damage(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + if (event.GetCause() != DamageCause.PROJECTILE) + { + return; + } + + Projectile projectile = event.GetProjectile(); + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(true); + + if (projectile == null) + { + return; + } + + if (!projectile.hasMetadata("BARBED_ARROW")) + { + return; + } + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (!getEntity().equals(damager)) + { + return; + } + + // Level + if (BARBED_LEVEL == 0) + { + return; + } + + Player damageePlayer = event.GetDamageePlayer(); + + if (damageePlayer != null) + { + damageePlayer.setSprinting(false); + } + + // Damage + event.AddMod(damager.getName(), "Barbed Arrows", projectile.getMetadata("BARBED_ARROW").get(0).asDouble(), false); + + // Condition + ClansManager.getInstance().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true); + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/GhastMiniboss.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/GhastMiniboss.java new file mode 100644 index 00000000..d618923f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/GhastMiniboss.java @@ -0,0 +1,136 @@ +package mineplex.game.clans.clans.nether.miniboss.bosses; + +import java.util.Random; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.LargeFireball; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.amplifiers.AmplifierManager; +import mineplex.game.clans.clans.nether.miniboss.MinibossFireball; +import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; + +/** + * Class for running an individual Ghast miniboss + */ +public class GhastMiniboss extends NetherMiniBoss +{ + private static final long MAIN_FIREBALL_COOLDOWN = 5000; + private static final long FIREBALL_LAUNCH_RATE = 500; + private static final int FIREBALLS_PER_USE = 5; + private static final double RUNE_DROP_CHANCE = .02; + private static final int MAX_VALUABLE_DROPS = 5; + private static final Material[] VALUABLE_DROP_TYPES = new Material[] {Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.LEATHER}; + private static final double MAX_TARGET_RANGE = 25; + private static final Material[] SET_DROP_TYPES = new Material[] {Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS}; + private static final double SET_DROP_CHANCE = .02; + private long _lastFireballUse; + private int _fireballsRemaining; + + public GhastMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + super(displayName, maxHealth, spawn, type); + } + + private void tryFireballVolley() + { + if (_fireballsRemaining > 0) + { + if (UtilTime.elapsed(_lastFireballUse, FIREBALL_LAUNCH_RATE)) + { + _fireballsRemaining--; + _lastFireballUse = System.currentTimeMillis(); + MinibossFireball.launchFireball(getEntity()); + } + } + else + { + if (UtilTime.elapsed(_lastFireballUse, MAIN_FIREBALL_COOLDOWN)) + { + _fireballsRemaining = FIREBALLS_PER_USE; + } + } + } + + @Override + public void customSpawn() + { + _lastFireballUse = System.currentTimeMillis(); + _fireballsRemaining = 0; + } + + @Override + public void customDeath(Location deathLocation) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(VALUABLE_DROP_TYPES[UtilMath.r(VALUABLE_DROP_TYPES.length)], UtilMath.r(MAX_VALUABLE_DROPS) + 1)); + double runeDropChance = RUNE_DROP_CHANCE; + if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) + { + runeDropChance *= AmplifierManager.AMPLIFIER_RUNE_DROP_MULTIPLIER; + } + if (new Random().nextDouble() <= runeDropChance) + { + RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; + deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); + } + if (new Random().nextDouble() <= SET_DROP_CHANCE) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(SET_DROP_TYPES[UtilMath.r(SET_DROP_TYPES.length)], 1)); + } + } + + @Override + public void update() + { + Player target = null; + for (Player test : UtilPlayer.getInRadius(getEntity().getLocation(), MAX_TARGET_RANGE).keySet()) + { + if (test.getGameMode() == GameMode.SURVIVAL && !ClansManager.getInstance().getIncognitoManager().Get(test).Hidden) + { + target = test; + break; + } + } + if (target != null) + { + UtilEnt.LookAt(getEntity(), target.getLocation()); + tryFireballVolley(); + } + } + + @EventHandler + public void onShoot(ProjectileLaunchEvent event) + { + if (event.getEntity().getShooter() != null && event.getEntity().getShooter().equals(getEntity())) + { + if (!(event.getEntity() instanceof LargeFireball)) + { + event.setCancelled(true); + } + ClansManager.getInstance().runSyncLater(() -> + { + if (event.getEntity() == null || event.getEntity().isDead() || !event.getEntity().isValid()) + { + return; + } + if (!MinibossFireball.isFireball(event.getEntity())) + { + event.getEntity().remove(); + } + }, 1L); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/WarriorMiniboss.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/WarriorMiniboss.java new file mode 100644 index 00000000..d978515d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/miniboss/bosses/WarriorMiniboss.java @@ -0,0 +1,157 @@ +package mineplex.game.clans.clans.nether.miniboss.bosses; + +import java.util.Random; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.amplifiers.AmplifierManager; +import mineplex.game.clans.clans.nether.miniboss.NetherMiniBoss; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +/** + * Class for running an individual Warrior miniboss + */ +public class WarriorMiniboss extends NetherMiniBoss +{ + private static final double RUNE_DROP_CHANCE = .02; + private static final int MAX_VALUABLE_DROPS = 5; + private static final Material[] VALUABLE_DROP_TYPES = new Material[] {Material.DIAMOND, Material.GOLD_INGOT, Material.IRON_INGOT, Material.LEATHER}; + private static final Material[] SET_DROP_TYPES = new Material[] {Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS}; + private static final double SET_DROP_CHANCE = .02; + private static final double LEAP_CHANCE = .9; + private static final double LEAP_MIN_DIST = 3; + private static final double LEAP_MAX_DIST = 16; + private static final float SOUND_VOLUME = 1f; + private static final float SOUND_PITCH = 2f; + + public WarriorMiniboss(String displayName, Double maxHealth, Location spawn, EntityType type) + { + super(displayName, maxHealth, spawn, type); + } + + @Override + public void customSpawn() + { + Zombie entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setHelmet(new ItemStack(Material.IRON_HELMET)); + eq.setChestplate(new ItemStack(Material.IRON_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.IRON_LEGGINGS)); + eq.setBoots(new ItemStack(Material.IRON_BOOTS)); + eq.setItemInHand(new ItemStack(Material.STONE_SWORD)); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + eq.setItemInHandDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void customDeath(Location deathLocation) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(VALUABLE_DROP_TYPES[UtilMath.r(VALUABLE_DROP_TYPES.length)], UtilMath.r(MAX_VALUABLE_DROPS) + 1)); + double runeDropChance = RUNE_DROP_CHANCE; + if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) + { + runeDropChance *= AmplifierManager.AMPLIFIER_RUNE_DROP_MULTIPLIER; + } + if (new Random().nextDouble() <= runeDropChance) + { + RuneAttribute runeType = RuneAttribute.values()[UtilMath.r(RuneAttribute.values().length)]; + deathLocation.getWorld().dropItemNaturally(deathLocation, ClansManager.getInstance().getGearManager().getRuneManager().getRune(runeType)); + } + if (new Random().nextDouble() <= SET_DROP_CHANCE) + { + deathLocation.getWorld().dropItemNaturally(deathLocation, new ItemStack(SET_DROP_TYPES[UtilMath.r(SET_DROP_TYPES.length)], 1)); + } + } + + @Override + public void update() + { + if (Math.random() < LEAP_CHANCE) + return; + + Zombie zombie = getEntity(); + + if (zombie.getTarget() == null) + return; + + double dist = UtilMath.offset(zombie.getTarget(), zombie); + + if (dist <= LEAP_MIN_DIST || dist > LEAP_MAX_DIST) + return; + + + double power = 0.8 + (1.2 * ((dist-3)/13d)); //Im sorry connor but i have no idea what those numbers are for <3 + + //Leap + UtilAction.velocity(zombie, UtilAlg.getTrajectory(zombie, zombie.getTarget()), + power, false, 0, 0.2, 1, true); + + //Effect + zombie.getWorld().playSound(zombie.getLocation(), Sound.ZOMBIE_HURT, SOUND_VOLUME, SOUND_PITCH); + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverData.java new file mode 100644 index 00000000..1754224e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverData.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.clans.observer; + +import java.util.EnumSet; + +import org.bukkit.entity.Player; + +import mineplex.core.common.player.PlayerSnapshot; + +public class ObserverData +{ + private PlayerSnapshot _snapshot; + private EnumSet _settings; + + public ObserverData(Player player) + { + _snapshot = PlayerSnapshot.getSnapshot(player); + _settings = EnumSet.noneOf(ObserverSettings.class); + } + + public PlayerSnapshot getSnapshot() + { + return _snapshot; + } + + public EnumSet getSettings() + { + return _settings; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverManager.java new file mode 100644 index 00000000..fdd3cb87 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverManager.java @@ -0,0 +1,210 @@ +package mineplex.game.clans.clans.observer; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.GameMode; +import org.bukkit.block.Chest; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +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.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.observer.command.ObserverCommand; +import mineplex.minecraft.game.core.condition.Condition; +import mineplex.minecraft.game.core.condition.Condition.ConditionType; +import mineplex.minecraft.game.core.condition.ConditionManager; + +public class ObserverManager extends MiniPlugin +{ + public enum Perm implements Permission + { + OBSERVE_COMMAND, + } + + // Used to Cloak Players + private final ConditionManager _conditionManager; + private final Map _observerMap; + + public ObserverManager(JavaPlugin plugin, ConditionManager conditionManager, ClansManager clansManager) + { + super("Observer", plugin); + + _conditionManager = conditionManager; + _observerMap = new HashMap<>(); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.TRAINEE.setPermission(Perm.OBSERVE_COMMAND, true, true); + } + + public void setObserver(Player player) + { + ObserverData data = new ObserverData(player); + ((CraftPlayer) player).getHandle().spectating = true; + _conditionManager.Clean(player); + _conditionManager.Factory().Cloak("Observer", player, null, Integer.MAX_VALUE, true, true); + UtilPlayer.clearInventory(player); + UtilPlayer.clearPotionEffects(player); + player.setGameMode(GameMode.CREATIVE); + ClansManager.getInstance().getGearManager().getPlayerGear(player).updateCache(true); + _observerMap.put(player, data); + } + + public void removeObserver(Player player) + { + ObserverData data = _observerMap.get(player); + restore(player, data); + _observerMap.remove(player); + } + + public boolean isObserver(Player player) + { + return _observerMap.containsKey(player); + } + + private void restore(Player player, ObserverData data) + { + data.getSnapshot().applySnapshot(player); + player.setGameMode(GameMode.SURVIVAL); + ((CraftPlayer) player).getHandle().spectating = false; + + Condition condition = _conditionManager.GetActiveCondition(player, ConditionType.CLOAK); + + if (condition != null) + { + condition.Expire(); + } + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) + { + if (_observerMap.containsKey(event.getDamager()) || _observerMap.containsKey(event.getEntity())) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onInteract(PlayerInteractEvent event) + { + ObserverData data = _observerMap.get(event.getPlayer()); + + if (data != null) + { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getState() instanceof Chest) + { + if (!data.getSettings().contains(ObserverSettings.CAN_OPEN_CHESTS)) + { + notify(event.getPlayer(), "You cannot open chests as an observer"); + event.setCancelled(true); + } + } + else + { + if (!data.getSettings().contains(ObserverSettings.CAN_INTERACT)) + { + notify(event.getPlayer(), "You cannot interact as an observer"); + event.setCancelled(true); + } + } + } + } + + @EventHandler + public void onBreak(BlockBreakEvent event) + { + ObserverData data = _observerMap.get(event.getPlayer()); + + if (data != null) + { + if (!data.getSettings().contains(ObserverSettings.CAN_BREAK_BLOCKS)) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) + { + ObserverData data = _observerMap.get(event.getWhoClicked()); + + if (data != null) + { + if (!data.getSettings().contains(ObserverSettings.CAN_CLICK_INVENTORY)) + { + event.setCancelled(true); + } + } + } + + @EventHandler (priority = EventPriority.LOWEST) + public void onPickup(PlayerPickupItemEvent event) + { + ObserverData data = _observerMap.get(event.getPlayer()); + + if (data != null) + { + if (!data.getSettings().contains(ObserverSettings.CAN_PICKUP_ITEMS)) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + if (_observerMap.containsKey(event.getPlayer())) + { + restore(event.getPlayer(), _observerMap.get(event.getPlayer())); + _observerMap.remove(event.getPlayer()); + } + } + + @Override + public void disable() + { + super.disable(); + + for (Map.Entry entry : _observerMap.entrySet()) + { + restore(entry.getKey(), entry.getValue()); + } + } + + public boolean canEnterObserverMode(Player player, boolean notify) + { + return true; + } + + private void notify(Player player, String message) + { + UtilPlayer.message(player, F.main("Observer", message)); + } + + @Override + public void addCommands() + { + addCommand(new ObserverCommand(this)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverSettings.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverSettings.java new file mode 100644 index 00000000..23bfc046 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/ObserverSettings.java @@ -0,0 +1,10 @@ +package mineplex.game.clans.clans.observer; + +public enum ObserverSettings +{ + CAN_OPEN_CHESTS, + CAN_BREAK_BLOCKS, + CAN_INTERACT, + CAN_PICKUP_ITEMS, + CAN_CLICK_INVENTORY; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/command/ObserverCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/command/ObserverCommand.java new file mode 100644 index 00000000..ed9e13fc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/observer/command/ObserverCommand.java @@ -0,0 +1,60 @@ +package mineplex.game.clans.clans.observer.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.observer.ObserverManager; + +public class ObserverCommand extends CommandBase +{ + public ObserverCommand(ObserverManager plugin) + { + super(plugin, ObserverManager.Perm.OBSERVE_COMMAND, "observer", "o"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length == 0) + { + // Toggle Observer Mode + if (Plugin.isObserver(caller)) + { + Plugin.removeObserver(caller); + UtilPlayer.message(caller, F.main("Observer", "You are no longer in " + F.elem("Observer Mode"))); + } + else + { + if (!Plugin.canEnterObserverMode(caller, true)) + { + return; + } + + Plugin.setObserver(caller); + UtilPlayer.message(caller, F.main("Observer", "You have entered " + F.elem("Observer Mode"))); + } + } + else + { + String playername = args[0]; + Player player = UtilPlayer.searchOnline(caller, playername, true); + + if (player != null) + { + // Observe Player + + if (Plugin.isObserver(caller)) + { + caller.teleport(player); + UtilPlayer.message(caller, F.main("Observer", "Teleported to " + F.elem(player.getName()))); + } + else + { + UtilPlayer.message(caller, F.main("Observer", "You must enter " + F.elem("Observer Mode") + " to teleport")); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/PlayingClient.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/PlayingClient.java new file mode 100644 index 00000000..e7a80557 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/PlayingClient.java @@ -0,0 +1,18 @@ +package mineplex.game.clans.clans.playtime; + +import org.bukkit.entity.Player; + +import mineplex.core.task.TaskManager; +import mineplex.game.clans.clans.ClansPlayerTasks; + +public class PlayingClient +{ + public long StartTime; + public boolean FirstSession; + + public PlayingClient(Player player, TaskManager taskManager) + { + StartTime = System.currentTimeMillis(); + FirstSession = taskManager.hasCompletedTask(player, ClansPlayerTasks.FIRST_SESSION.id()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/Playtime.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/Playtime.java new file mode 100644 index 00000000..544193db --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/Playtime.java @@ -0,0 +1,103 @@ +package mineplex.game.clans.clans.playtime; + +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.MiniClientPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.stats.StatsManager; +import mineplex.core.task.TaskManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansPlayerStats; +import mineplex.game.clans.clans.playtime.command.PlayTimeCommand; + +public class Playtime extends MiniClientPlugin +{ + public enum Perm implements Permission + { + CLANS_TIME_COMMAND, + } + + private StatsManager _statsManager; + + public Playtime(ClansManager clans, StatsManager statsManager) + { + super("Clans Play Time Tracker", clans.getPlugin()); + + _statsManager = statsManager; + + addCommand(new PlayTimeCommand(_statsManager, this)); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.MOD.setPermission(Perm.CLANS_TIME_COMMAND, true, true); + } + + @Override + public void disable() + { + for (Player player : Bukkit.getOnlinePlayers()) + { + save(player); + } + } + + // Seconds + public long getPlaytime(Player player) + { + return _statsManager.Get(player).getStat(ClansPlayerStats.PLAY_TIME.id()); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + Set(event.getPlayer(), addPlayer(event.getPlayer().getUniqueId())); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) + { + save(event.getPlayer()); + } + + @EventHandler + public void onPlayerKicked(PlayerKickEvent event) + { + save(event.getPlayer()); + } + + private void save(Player player) + { + long timePlaying = getUnsavedPlaytime(player); + + _statsManager.incrementStat(player, ClansPlayerStats.PLAY_TIME.id(), timePlaying); + + // Increment main time in game as well + _statsManager.incrementStat(player, "Global.TimeInGame", timePlaying); + + Get(player).StartTime = System.currentTimeMillis(); + } + + @Override + protected PlayingClient addPlayer(UUID uuid) + { + return new PlayingClient(Bukkit.getPlayer(uuid), TaskManager.Instance); + } + + // Seconds + public long getUnsavedPlaytime(Player player) + { + return (System.currentTimeMillis() - Get(player).StartTime) / 1000; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/command/PlayTimeCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/command/PlayTimeCommand.java new file mode 100644 index 00000000..0e121a68 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/playtime/command/PlayTimeCommand.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.clans.playtime.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.stats.StatsManager; +import mineplex.game.clans.clans.ClansPlayerStats; +import mineplex.game.clans.clans.playtime.Playtime; + +public class PlayTimeCommand extends CommandBase +{ + private Playtime _playTracker; + + public PlayTimeCommand(StatsManager plugin, Playtime tracker) + { + super(plugin, Playtime.Perm.CLANS_TIME_COMMAND, "clanstime"); + + _playTracker = tracker; + } + + @Override + public void Execute(final Player caller, final String[] args) + { + if (args == null || args.length == 0) + { + UtilPlayer.message(caller, F.main("Clans", "Usage: /clanstime ")); + } + else + { + final Player target = UtilPlayer.searchOnline(caller, args[0], false); + + if (target == null) + { + Plugin.getOfflinePlayerStats(args[0], stats -> + { + if (stats == null) + { + UtilPlayer.message(caller, F.main("Clans", "Player " + F.elem(args[0]) + " not found!")); + } + else + { + long time = stats.getStat(ClansPlayerStats.PLAY_TIME.id()); + UtilPlayer.message(caller, F.main("Clans", F.name(args[0]) + " has spent " + F.elem(UtilTime.convertString(time * 1000L, 1, UtilTime.TimeUnit.FIT)) + " playing Clans.")); + } + }); + } + else + { + long time = Plugin.Get(target).getStat(ClansPlayerStats.PLAY_TIME.id()); + UtilPlayer.message(caller, F.main("Clans", F.name(target.getName()) + " has spent " + F.elem(UtilTime.convertString(time * 1000L, 1, UtilTime.TimeUnit.FIT) + " (+" + UtilTime.MakeStr(_playTracker.getUnsavedPlaytime(target) * 1000) + ")") + " playing Clans.")); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/potato/PotatoManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/potato/PotatoManager.java new file mode 100644 index 00000000..c977fc41 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/potato/PotatoManager.java @@ -0,0 +1,144 @@ +package mineplex.game.clans.clans.potato; + +import java.util.Iterator; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilInv; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.projectile.IThrown; +import mineplex.core.projectile.ProjectileUser; +import mineplex.game.clans.clans.ClansManager; + +public class PotatoManager extends MiniPlugin implements IThrown +{ + private static final String POTATO_NAME = C.cGray + "Potato"; + + private ClansManager _clansManager; + + public PotatoManager(JavaPlugin plugin, ClansManager clansManager) + { + super("Potato", plugin); + + _clansManager = clansManager; + } + + @EventHandler + public void onRespawn(PlayerRespawnEvent event) + { + give(event.getPlayer(), 5); + } + + private void give(Player player, int count) + { + ItemStack potato = new ItemStack(Material.BAKED_POTATO, count); + ItemMeta meta = potato.getItemMeta(); + meta.setDisplayName(POTATO_NAME); + potato.setItemMeta(meta); + player.getInventory().addItem(potato); + } + + public boolean isPotato(ItemStack item) + { + if (item == null) + return false; + else if (item.getType() != Material.BAKED_POTATO) + return false; + else + return item.getItemMeta() != null && POTATO_NAME.equals(item.getItemMeta().getDisplayName()); + } + + @EventHandler + public void tossPotato(PlayerInteractEvent event) + { + if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + Player player = event.getPlayer(); + ItemStack item = event.getPlayer().getItemInHand(); + if (isPotato(item)) + { + UtilInv.remove(event.getPlayer(), Material.BAKED_POTATO, (byte) 0, 1); + UtilInv.Update(event.getPlayer()); + + Item ent = player.getWorld().dropItem(player.getEyeLocation(), ItemStackFactory.Instance.CreateStack(Material.BAKED_POTATO)); + UtilAction.velocity(ent, player.getLocation().getDirection(), 1.2, false, 0, 0.2, 10, false); + _clansManager.getProjectile().AddThrow(ent, player, this, -1, true, true, true, false, 0.5f); + } + } + } + + @EventHandler + public void onItemDrop(PlayerDropItemEvent event) + { + ItemStack item = event.getItemDrop().getItemStack(); + if (isPotato(item)) + { + event.setCancelled(true); + ItemStack hand = event.getPlayer().getItemInHand(); + if (hand != null && isPotato(hand)) + { + hand.setAmount(hand.getAmount() - 1); + event.getPlayer().setItemInHand(hand); + } + } + } + + @EventHandler + public void onDeath(PlayerDeathEvent event) + { + Iterator iterator = event.getDrops().iterator(); + while (iterator.hasNext()) + { + if (isPotato(iterator.next())) iterator.remove(); + } + } + + @Override + public void Collide(LivingEntity target, Block block, ProjectileUser data) + { + if (target instanceof Player) + { + Player player = ((Player) target); + give(player, 1); + } + + data.getThrown().getWorld().playSound(data.getThrown().getLocation(), Sound.CHICKEN_EGG_POP, 1f, 1.6f); + + data.getThrown().remove(); + } + + @Override + public void Idle(ProjectileUser data) + { + + } + + @Override + public void Expire(ProjectileUser data) + { + + } + + @Override + public void ChunkUnload(ProjectileUser data) + { + data.getThrown().remove(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/pvptimer/PvPTimerManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/pvptimer/PvPTimerManager.java new file mode 100644 index 00000000..1b7a5e6d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/pvptimer/PvPTimerManager.java @@ -0,0 +1,389 @@ +package mineplex.game.clans.clans.pvptimer; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.WeakHashMap; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import org.apache.commons.io.FileUtils; +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.recharge.Recharge; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +@ReflectivelyCreateMiniPlugin +public class PvPTimerManager extends MiniPlugin +{ + public enum Perm implements Permission + { + PVP_ENABLE_SELF, + PVP_ENABLE_OTHER, + } + + private final File _directory; + private final Map _timers = new WeakHashMap<>(); + + public PvPTimerManager() + { + super("PvP Timer"); + + _directory = new File("pvptimers"); + if (!_directory.exists()) + { + _directory.mkdir(); + } + if (!_directory.isDirectory()) + { + FileUtils.deleteQuietly(_directory); + _directory.mkdir(); + } + + addCommand(new CommandBase(this, Perm.PVP_ENABLE_SELF, "pvp") + { + public void Execute(Player caller, String[] args) + { + if (!hasTimer(caller)) + { + UtilPlayer.message(caller, F.main(getName(), "You do not have a PvP Timer!")); + return; + } + + disableTimer(caller, true, true); + } + }); + addCommand(new CommandBase(this, Perm.PVP_ENABLE_OTHER, "enablepvp") + { + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /enablepvp ")); + return; + } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) + { + UtilPlayer.message(caller, F.main(getName(), F.elem(args[0]) + " was not found!")); + return; + } + + if (hasTimer(target)) + { + disableTimer(target, true, true); + UtilPlayer.message(caller, F.main(getName(), F.elem(target.getName()) + " no longer has a PvP Timer!")); + if (!UtilServer.isTestServer()) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", + new SlackMessage("Clans Command Logger", "crossed_swords", caller.getName() + " has removed " + target.getName() + "'s PvP Timer on " + UtilServer.getServerName() + "."), + true); + } + } + else + { + UtilPlayer.message(caller, F.main(getName(), F.elem(target.getName()) + " does not have a PvP Timer!")); + } + } + }); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.PLAYER.setPermission(Perm.PVP_ENABLE_SELF, true, true); + PermissionGroup.CMOD.setPermission(Perm.PVP_ENABLE_OTHER, false, true); + PermissionGroup.ADMIN.setPermission(Perm.PVP_ENABLE_OTHER, true, true); + } + + private String getPvPTimerFile(String fileName) throws IOException + { + return _directory.getCanonicalFile() + File.separator + fileName; + } + + private boolean addPvPTimer(Player player) + { + try + { + File file = new File(getPvPTimerFile(player.getUniqueId().toString() + ".pvp")); + boolean add = !FileUtils.directoryContains(_directory, file); + + if (add) + { + long start = System.currentTimeMillis(); + FileUtils.write(file, String.valueOf(start), Charset.defaultCharset(), false); + _timers.put(player, start); + } + else + { + String read = FileUtils.readFileToString(file, Charset.defaultCharset()); + long parsed = Long.parseLong(read); + if (parsed != -1 && !UtilTime.elapsed(parsed, 60 * 60 * 1000)) + { + _timers.put(player, parsed); + } + } + + return add; + } + catch (IOException | NumberFormatException e) + { + e.printStackTrace(); + return false; + } + } + + private void disableTimer(Player player, boolean removeFromMap, boolean inform) + { + try + { + File file = new File(getPvPTimerFile(player.getUniqueId().toString() + ".pvp")); + if (file.exists()) + { + FileUtils.write(file, String.valueOf(-1L), Charset.defaultCharset(), false); + if (removeFromMap) + { + _timers.remove(player); + } + if (inform) + { + UtilPlayer.message(player, F.main(getName(), "Your PvP Protection has been removed!")); + } + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + public boolean hasTimer(Player player) + { + if (_timers.containsKey(player)) + { + if (UtilTime.elapsed(_timers.get(player), 60 * 60 * 1000)) + { + _timers.remove(player); + } + else + { + return true; + } + } + + return false; + } + + @SuppressWarnings("deprecation") + public boolean handleMining(Player player, Block block, boolean playSound, ItemStack overrideDrop, boolean setToAir) + { + if (!hasTimer(player)) + { + return false; + } + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId()); + Function, ItemStack[]> converter = (collection) -> + { + ItemStack[] array = new ItemStack[collection.size()]; + int i = 0; + for (ItemStack item : collection) + { + array[i++] = item; + } + return array; + }; + BiConsumer dropper = (integer, item) -> + { + block.getWorld().dropItemNaturally(block.getLocation().add(0.5, 0.3, 0.5), item); + }; + Collection drops = overrideDrop != null ? Arrays.asList(overrideDrop) : block.getDrops(player.getItemInHand()); + player.getInventory().addItem(converter.apply(drops)).forEach(dropper); + if (setToAir) + { + block.setType(Material.AIR); + } + + return true; + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + if (addPvPTimer(event.getPlayer())) + { + runSyncLater(() -> UtilPlayer.message(event.getPlayer(), F.main(getName(), "You now have 1 hour of PvP Protection!")), 40L); + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + Iterator> timers = _timers.entrySet().iterator(); + while (timers.hasNext()) + { + Entry timer = timers.next(); + if (UtilTime.elapsed(timer.getValue(), 60 * 60 * 1000)) + { + UtilPlayer.message(timer.getKey(), F.main(getName(), "Your PvP Protection has expired!")); + disableTimer(timer.getKey(), false, false); + timers.remove(); + } + } + } + + @EventHandler + public void onSkill(SkillTriggerEvent event) + { + if (hasTimer(event.GetPlayer())) + { + UtilPlayer.message(event.GetPlayer(), F.main("Clans", "You cannot use skills whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + event.SetCancelled(true); + } + } + + @EventHandler + public void onShoot(EntityShootBowEvent event) + { + if (event.getEntity() instanceof Player) + { + Player player = (Player) event.getEntity(); + + if (hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot shoot whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + event.setCancelled(true); + } + } + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageePlayer() != null) + { + if (hasTimer(event.GetDamageePlayer()) && event.GetDamagerPlayer(true) != null) + { + UtilPlayer.message(event.GetDamagerPlayer(true), F.main(getName(), "You cannot harm " + F.elem(event.GetDamageePlayer().getName()) + "!")); + event.SetCancelled("PvP Timer"); + } + if (event.GetDamagerPlayer(true) != null) + { + if (hasTimer(event.GetDamagerPlayer(true))) + { + UtilPlayer.message(event.GetDamagerPlayer(true), F.main(getName(), "You cannot harm " + F.elem(event.GetDamageePlayer().getName()) + " whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + event.SetCancelled("PvP Timer"); + } + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPickup(PlayerPickupItemEvent event) + { + if (hasTimer(event.getPlayer())) + { + event.setCancelled(true); + if (Recharge.Instance.use(event.getPlayer(), "PvP Timer Inform NoPickup", 5000, false, false)) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot pick up items whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) + { + if (handleMining(event.getPlayer(), event.getBlock(), true, null, true)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEnter(PlayerMoveEvent event) + { + if (!hasTimer(event.getPlayer()) || UtilWorld.areChunksEqual(event.getFrom(), event.getTo()) || ClansManager.getInstance().getClanUtility().isAdmin(event.getTo())) + { + return; + } + ClanTerritory claimTo = ClansManager.getInstance().getClanUtility().getClaim(event.getTo()); + ClanTerritory claimFrom = ClansManager.getInstance().getClanUtility().getClaim(event.getFrom()); + + if (claimTo != null && ClansManager.getInstance().getClanUtility().getAccess(event.getPlayer(), event.getTo()) != ClanRelation.SELF) + { + if (claimFrom == null || !claimFrom.Owner.equals(claimTo.Owner)) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot enter claimed land whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + Vector trajectory = UtilAlg.getTrajectory(event.getTo(), event.getFrom()).multiply(4); + event.getPlayer().teleport(event.getFrom().clone().add(trajectory)); + UtilAction.velocity(event.getPlayer(), trajectory, 1.5, true, 0.8, 0, 1.0, true); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onTeleportInto(PlayerTeleportEvent event) + { + if (!hasTimer(event.getPlayer()) || UtilWorld.areChunksEqual(event.getFrom(), event.getTo()) || ClansManager.getInstance().getClanUtility().isAdmin(event.getTo())) + { + return; + } + ClanTerritory claimTo = ClansManager.getInstance().getClanUtility().getClaim(event.getTo()); + ClanTerritory claimFrom = ClansManager.getInstance().getClanUtility().getClaim(event.getFrom()); + + if (claimTo != null && ClansManager.getInstance().getClanUtility().getAccess(event.getPlayer(), event.getTo()) != ClanRelation.SELF) + { + if (claimFrom == null || !claimFrom.Owner.equals(claimTo.Owner)) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot enter claimed land whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + event.setCancelled(true); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/redis/ClanDeleteCommandHandler.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/redis/ClanDeleteCommandHandler.java new file mode 100644 index 00000000..c08e9425 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/redis/ClanDeleteCommandHandler.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.clans.redis; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.core.ClanDeleteCommand; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.ServerCommand; + +public class ClanDeleteCommandHandler implements CommandCallback +{ + + public void run(ServerCommand command) + { + if (command instanceof ClanDeleteCommand) + { + ClanDeleteCommand serverCommand = (ClanDeleteCommand) command; + String clanName = serverCommand.getClanName(); + ClanInfo clanInfo = ClansManager.getInstance().getClan(clanName); + + if (clanInfo != null) + { + // Kick all online players from clan and delete clan info locally + UtilPlayer.kick(clanInfo.getOnlinePlayers(), "Clans", "Your clan leader has moved your clan to another server!", true); + ClansManager.getInstance().getClanDataAccess().deleteLocally(clanInfo); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/redis/ClanLoadCommandHandler.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/redis/ClanLoadCommandHandler.java new file mode 100644 index 00000000..54274dd5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/redis/ClanLoadCommandHandler.java @@ -0,0 +1,41 @@ +package mineplex.game.clans.clans.redis; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.core.ClanDeleteCommand; +import mineplex.game.clans.core.ClanLoadCommand; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.ServerCommand; + +public class ClanLoadCommandHandler implements CommandCallback +{ + + public void run(ServerCommand command) + { + if (command instanceof ClanLoadCommand) + { + ClanLoadCommand serverCommand = (ClanLoadCommand) command; + final String clanName = serverCommand.getClanName(); + + ClansManager.getInstance().getClanDataAccess().retrieveClan(clanName, new Callback() + { + @Override + public void run(ClanToken clan) + { + if (clan != null) + { + ClansManager.getInstance().loadClan(clan); // Load the clan data locally + System.out.println("Successfully finished loading and transferring clan '" + clanName + "'!"); + } + else + { + System.out.println("ERROR: UNABLE TO LOAD CLAN " + clanName + " DURING REMOTE CLAN LOAD COMMAND!"); + } + } + }); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java new file mode 100644 index 00000000..012fdc19 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/regions/ClansRegions.java @@ -0,0 +1,225 @@ +package mineplex.game.clans.clans.regions; + +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.WorldBorder; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.Callback; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.spawn.Spawn; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTeleportEvent; + +public class ClansRegions extends MiniPlugin +{ + public final static String DEFAULT_WORLD_NAME = "world"; + public final static int SPAWN_RADIUS = 3; // Radius of spawn claim area (measured in chunks) + public final static int SHOP_RADIUS = 6; // Radius of shop claim area (measured in chunks) + public final static int FIELDS_RADIUS = 7; // Radius of fields claim area (measured in chunks) + public final static int BORDERLANDS_RADIUS = 85; // Radius of borderlands claim area (measured in chunks) + public static final int BORDER_RADIUS = 1280; + + private ClansManager _manager; + private World _world; + + public ClansRegions(JavaPlugin plugin, ClansManager manager, String worldName) + { + super("Clans Regions" + worldName, plugin); + _manager = manager; + _world = Bukkit.getWorld(worldName); + initializeBorder(); + } + + public ClansRegions(JavaPlugin plugin, ClansManager manager) + { + this(plugin, manager, DEFAULT_WORLD_NAME); + } + + public void initializeRegions() + { + Location worldCenter = new Location(_world, 0, 0, 0); + + // Initialize Spawn faction and claims + claimArea("Spawn", SPAWN_RADIUS, 0, false, true, new Location[] { Spawn.getNorthSpawn(), Spawn.getSouthSpawn() }); + + claimArea("Shops", 2, 0, true, false, new Location[]{Spawn.getWestTownCenter(), Spawn.getEastTownCenter()}); + claimArea("Shops", SHOP_RADIUS, 3, false, false, new Location[]{Spawn.getWestTownCenter(), Spawn.getEastTownCenter()}); + + // Initialize Fields and Borderlands factions and claims + claimArea("Fields", FIELDS_RADIUS, 0, false, true, worldCenter); + claimArea("Borderlands", BORDERLANDS_RADIUS, 48, false, true, worldCenter); + + debugClan("Spawn"); + debugClan("Shops"); + debugClan("Fields"); + debugClan("Borderlands"); + } + + public void initializeBorder() + { + WorldBorder worldBorder = _world.getWorldBorder(); + worldBorder.setCenter(0, 0); + worldBorder.setSize(BORDER_RADIUS * 2); + } + + public void debugClan(String clanName) + { + ClanInfo clan = _manager.getClan(clanName); + + if (clan != null) + { + System.out.println("Clan " + clanName + " has " + clan.getClaimSet().size() + " claims!"); + } + else + { + System.out.println("NO CLAN FOUND BY NAME " + clanName); + } + } + + public void resetRegions() + { + clearClaims("Spawn"); + clearClaims("Shops"); + clearClaims("Fields"); + clearClaims("Borderlands"); + initializeRegions(); + } + + private void clearClaims(String name) + { + ClanInfo clan = _manager.getClan(name); + + if (clan == null) + { + return; + } + + System.out.println("Clearing claims for " + name + " with clan id " + clan + "!"); + + for (ClaimLocation chunk : clan.getClaimSet()) + { + _manager.getClaimMap().remove(chunk); + } + + clan.getClaimSet().clear(); + _manager.getClanDataAccess().getRepository().removeTerritoryClaims(clan.getId()); + } + + /** + * Initializes a server-side clan and claims area according to the + * location and radius properties passed in. + * @param clanName - the name of the clan to create/claim territory for + * @param locations - the center location to begin the claim + * @param chunkRadius - the radius (in chunks) to claim + * @param claimOffset - the initial offset in claim (creating a 'hole' with chunk offset radius) + * @param safe - whether the chunk claimed is considered a 'safe' (pvp-free) region. + */ + public void claimArea(final String clanName, final int chunkRadius, final int claimOffset, final boolean safe, final boolean addNegative, final Location... locations) + { + final ClanInfo clan = _manager.getClan(clanName); + + if (clan == null) + { + _manager.getClanDataAccess().create("ClansRegions", clanName, true, new Callback() + { + @Override + public void run(ClanInfo data) + { + if (data != null) + { + for (Location location : locations) + { + claimArea(data, location, chunkRadius, claimOffset, addNegative, safe); + log(String.format("Initialized %s faction territory and creation!", clanName)); + } + + debugClan(clanName); + } + else + { + System.out.println("Clans Regions error!"); + System.out.println("Seek out help!"); + } + } + }); + } + else + { + for (Location location : locations) + { + claimArea(clan, location, chunkRadius, claimOffset, addNegative, safe); + } + } + } + + /*private void claimArea(String clanName, int chunkRadius, int claimOffset, boolean safe, Location... locations) + { + claimArea(clanName, chunkRadius, claimOffset, 0, safe, locations); + }*/ + + private void claimArea(ClanInfo clan, Location location, int chunkRadius, int claimOffset, boolean addNegative, boolean safe) + { + int chunkX = location.getChunk().getX(); + int chunkZ = location.getChunk().getZ(); + Set chunks = new HashSet<>(); + + int start = addNegative ? -chunkRadius - 1 : -chunkRadius; + + for (int xOffset = start; xOffset <= chunkRadius; xOffset++) + { + for (int zOffset = start; zOffset <= chunkRadius; zOffset++) + { + int x = chunkX + xOffset; + int z = chunkZ + zOffset; + ClaimLocation chunk = ClaimLocation.of(location.getWorld().getName(), x, z); + + if (addNegative) + { + if (((xOffset < 0 && Math.abs(xOffset) < (claimOffset + 1)) || (xOffset >= 0 && xOffset < claimOffset)) && + ((zOffset < 0 && Math.abs(zOffset) < (claimOffset + 1)) || (zOffset >= 0 && zOffset < claimOffset))) + continue; + } + else + { + if ((Math.abs(xOffset) < claimOffset) && (Math.abs(zOffset) < claimOffset)) + continue; + } + + if (_manager.getClaimMap().containsKey(chunk)) + { +// System.out.println("get claim map contains " + chunkStr); // this is really really slowing server startup down. just saying. + continue; + } + + chunks.add(chunk); + } + } + + if (chunks.size() > 0) + { + _manager.getClanDataAccess().claimAll(clan.getName(), "ClansRegions", safe, chunks.toArray(new ClaimLocation[chunks.size()])); + } + } + + @EventHandler + public void onSkillTeleport(SkillTeleportEvent event) + { + if (!isInsideBorders(event.getDestination())) + { + event.setCancelled(true); + } + } + + private boolean isInsideBorders(Location location) + { + return Math.abs(location.getBlockX()) < BORDER_RADIUS && Math.abs(location.getBlockZ()) < BORDER_RADIUS; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/ClansPlayerScoreboard.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/ClansPlayerScoreboard.java new file mode 100644 index 00000000..a938f496 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/ClansPlayerScoreboard.java @@ -0,0 +1,140 @@ +package mineplex.game.clans.clans.scoreboard; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilText; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.PlayerScoreboard; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; + +public class ClansPlayerScoreboard extends PlayerScoreboard +{ + private ClansManager _clansManager; + + public ClansPlayerScoreboard(ScoreboardManager manager, ClansManager clansManager, Player player) + { + super(manager, player); + _clansManager = clansManager; + } + + @Override + protected void addTeams(Player player) + { + refreshTeams(player); + } + + public void refreshTeams(Player player) + { + System.out.println("<--> SB refresh"); + for (Player otherPlayer : Bukkit.getOnlinePlayers()) + { + if (otherPlayer.equals(player)) + { + ClanInfo clan = _clansManager.getClan(player); + ClanRelation rel = _clansManager.getClanUtility().rel(clan, clan); + // Add Self to Self + add(getScoreboard(), otherPlayer, clan, rel, 0); + } + else + { + ClanInfo clan = _clansManager.getClan(player); + ClanInfo otherClan = _clansManager.getClan(otherPlayer); + ClanRelation rel = _clansManager.getClanUtility().rel(clan, otherClan); + int clanScore = (clan != null && otherClan != null) ? clan.getWarPoints(otherClan) : 0; + int otherClanScore = (clan != null && otherClan != null) ? otherClan.getWarPoints(clan) : 0; + + // Add Other to Self + add(getScoreboard(), otherPlayer, otherClan, rel, clanScore); + // Add Self to Other + add(otherPlayer.getScoreboard(), player, clan, rel, otherClanScore); + } + } + } + + public void removeFromAllTeams(Scoreboard scoreboard, Player player) + { + for (Team team : scoreboard.getTeams()) + { + if (team.hasPlayer(player)) + { + team.removePlayer(player); + } + } + } + + public void add(Scoreboard scoreboard, Player otherPlayer, ClanInfo clanInfo, ClanRelation relation, int ownScore) + { + if (otherPlayer.getGameMode().equals(GameMode.CREATIVE)) + { + String teamName = UtilText.trim(16, _clansManager.getClientManager().Get(otherPlayer).getPrimaryGroup().name() + "CREATIVE"); + Team team = scoreboard.getTeam(teamName); + if (team == null) + { + team = scoreboard.registerNewTeam(teamName); + if (!_clansManager.getClientManager().Get(otherPlayer).getPrimaryGroup().getDisplay(false, false, false, false).isEmpty()) + { + team.setPrefix(UtilText.trim(16, _clansManager.getClientManager().Get(otherPlayer).getPrimaryGroup().getDisplay(true, true, true, false) + ChatColor.RESET + " ")); + } + team.setSuffix(C.cRed + " STAFF MODE"); + } + + Objective domObjective; + if ((domObjective = scoreboard.getObjective(DisplaySlot.BELOW_NAME)) == null) + { + domObjective = scoreboard.registerNewObjective("war", "dummy"); + domObjective.setDisplayName("War Points"); + domObjective.setDisplaySlot(DisplaySlot.BELOW_NAME); + } + + if (clanInfo != null) + domObjective.getScore(otherPlayer.getName()).setScore(ownScore); + + team.addPlayer(otherPlayer); + + return; + } + + String teamName = getTeamName(clanInfo, relation, ownScore); + Team team = scoreboard.getTeam(teamName); + if (team == null) + { + team = scoreboard.registerNewTeam(teamName); + if (clanInfo != null) + team.setPrefix(relation.getColor(true) + clanInfo.getName() + relation.getColor(false) + " "); + else + team.setPrefix(relation.getColor(false).toString()); + } + + if (Clans.HARDCORE) + { + Objective domObjective; + if ((domObjective = scoreboard.getObjective(DisplaySlot.BELOW_NAME)) == null) + { + domObjective = scoreboard.registerNewObjective("war", "dummy"); + domObjective.setDisplayName("War Points"); + domObjective.setDisplaySlot(DisplaySlot.BELOW_NAME); + } + + if (clanInfo != null) + domObjective.getScore(otherPlayer.getName()).setScore(ownScore); + } + + team.addPlayer(otherPlayer); + } + + public String getTeamName(ClanInfo clanInfo, ClanRelation relation, int ownScore) + { + return (clanInfo == null ? "" : clanInfo.getId() + "") + relation.ordinal(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/ClansScoreboardManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/ClansScoreboardManager.java new file mode 100644 index 00000000..80d73923 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/ClansScoreboardManager.java @@ -0,0 +1,113 @@ +package mineplex.game.clans.clans.scoreboard; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.event.OnlinePrimaryGroupUpdateEvent; +import mineplex.core.donation.DonationManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.PlayerScoreboard; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardData; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.scoreboard.elements.ScoreboardElementClan; +import mineplex.game.clans.clans.scoreboard.elements.ScoreboardElementPlayer; +import mineplex.game.clans.clans.war.WarManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.tutorial.TutorialManager; + +public class ClansScoreboardManager extends ScoreboardManager +{ + private ClansManager _clansManager; + private WarManager _warManager; + private WorldEventManager _worldEvent; + private TutorialManager _tutorial; + + public ClansScoreboardManager(JavaPlugin plugin, ClansManager clansManager, WarManager warManager, WorldEventManager worldEvent, TutorialManager tutorial, CoreClientManager clientManager, DonationManager donationManager) + { + super(plugin, clientManager, donationManager, clansManager.getIncognitoManager()); + + _clansManager = clansManager; + _warManager = warManager; + _worldEvent = worldEvent; + _tutorial = tutorial; + + init(); + } + + private void init() + { + setTitle("Clans " + Clans.getMap()); + + ScoreboardData data = getData("default", true); + + data.writeElement(new ScoreboardElementClan(_clansManager)); + data.writeElement(new ScoreboardElementPlayer(_clansManager)); +// data.writeElement(new ScoreboardElementPlayerCount(_clansManager)); + + data.writeElement(_warManager); + data.writeElement(_worldEvent); + data.writeElement(_tutorial); + +// for (Tutorial tutorial : TutorialManager.Instance.getTutorials().values()) +// { +// data.writeElement(tutorial); +// } + } + + @EventHandler + public void onGamemodeChanged(PlayerGameModeChangeEvent event) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(_clansManager.getPlugin(), () -> + { + for (Player player : Bukkit.getOnlinePlayers()) + { + refresh(player); + } + }, 20); + } + + @EventHandler + public void onRankUpdate(OnlinePrimaryGroupUpdateEvent event) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(_clansManager.getPlugin(), () -> + { + for (Player player : Bukkit.getOnlinePlayers()) + { + refresh(player); + } + }, 20); + } + + @EventHandler + public void drawUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.FASTER) draw(); + } + + @Override + protected PlayerScoreboard createScoreboard(Player player) + { + return new ClansPlayerScoreboard(this, _clansManager, player); + } + + public void refresh(ClanInfo clanInfo) + { + for (Player player : clanInfo.getOnlinePlayers()) + { + refresh(player); + } + } + + public void refresh(Player player) + { + ((ClansPlayerScoreboard) getCurrentScoreboard(player)).refreshTeams(player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementClan.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementClan.java new file mode 100644 index 00000000..5d5bbafe --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementClan.java @@ -0,0 +1,54 @@ +package mineplex.game.clans.clans.scoreboard.elements; + +import java.util.List; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilTime; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.entity.Player; + +import com.google.common.collect.Lists; + +public class ScoreboardElementClan implements ScoreboardElement +{ + private ClansManager _clansManager; + + public ScoreboardElementClan(ClansManager clansManager) + { + _clansManager = clansManager; + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + List output = Lists.newArrayList(); + + ClanInfo clanInfo = _clansManager.getClan(player); + + if (clanInfo != null) + { + output.add(C.cYellowB + "Clan"); + output.add(_clansManager.getClanUtility().mRel(_clansManager.getRelation(player, player), clanInfo.getName(), false)); + output.add(" "); + // Energy + if (clanInfo.getEnergyCostPerMinute() > 0) + { + output.add(C.cYellowB + "Clan Energy"); + output.add(C.cGreen + UtilTime.convertString((clanInfo.getEnergy() / clanInfo.getEnergyCostPerMinute()) * 60000L, 1, UtilTime.TimeUnit.FIT)); + output.add(" "); + } + } + else + { + output.add(C.cYellowB + "Clan"); + output.add("No Clan"); + output.add(" "); + } + + return output; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementPlayer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementPlayer.java new file mode 100644 index 00000000..17ca2109 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementPlayer.java @@ -0,0 +1,70 @@ +package mineplex.game.clans.clans.scoreboard.elements; + +import java.util.List; + +import org.bukkit.entity.Player; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.C; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.game.clans.core.repository.ClanTerritory; + +public class ScoreboardElementPlayer implements ScoreboardElement +{ + private ClansManager _clansManager; + + public ScoreboardElementPlayer(ClansManager clansManager) + { + _clansManager = clansManager; + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + List output = Lists.newArrayList(); + output.add(C.cYellowB + "Gold"); + output.add(C.cGold + _clansManager.getGoldManager().Get(player).getBalance()); + + output.add(" "); + + output.add(C.cYellowB + "Territory"); + String regionString = C.xWilderness + "Wilderness"; + ClanTerritory claim = _clansManager.getClanUtility().getClaim(player.getLocation()); + if (claim != null) + { + //Relation + ClansUtility.ClanRelation relation = _clansManager.getClanUtility().relPT(player, claim.ClaimLocation); + + //Name + regionString = _clansManager.getClanUtility().mRel(relation, claim.Owner, false); + + //Trust + if (relation == ClansUtility.ClanRelation.ALLY_TRUST) + { + regionString += C.mBody + "(" + C.mElem + "Trusted" + C.mBody + ")"; + } + } + + if (_clansManager.getNetherManager().isInNether(player)) + { + regionString = C.cClansNether + "The Nether"; + if (_clansManager.getClanUtility().isSafe(player.getLocation())) + { + regionString = C.cClansNether + "Nether Spawn"; + } + } + + if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + regionString = C.cDRed + "Raid World"; + } + + output.add(regionString); + + return output; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementPlayerCount.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementPlayerCount.java new file mode 100644 index 00000000..c427499c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/scoreboard/elements/ScoreboardElementPlayerCount.java @@ -0,0 +1,32 @@ +package mineplex.game.clans.clans.scoreboard.elements; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.game.clans.clans.ClansManager; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class ScoreboardElementPlayerCount implements ScoreboardElement +{ + private ClansManager _clansManager; + + public ScoreboardElementPlayerCount(ClansManager clansManager) + { + _clansManager = clansManager; + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + List output = new ArrayList(); + + output.add(""); + output.add(C.cYellow + "Players " + C.cWhite + UtilServer.getPlayers().length + "/100"); + + return output; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/SiegeManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/SiegeManager.java new file mode 100644 index 00000000..0483354c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/SiegeManager.java @@ -0,0 +1,401 @@ +package mineplex.game.clans.clans.siege; + +import java.util.Stack; + +import net.minecraft.server.v1_8_R3.Material; + +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockPlaceEvent; + +import com.google.gson.Gson; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.siege.command.GiveWeaponCommand; +import mineplex.game.clans.clans.siege.outpost.OutpostManager; +import mineplex.game.clans.clans.siege.repository.SiegeWeaponRepository; +import mineplex.game.clans.clans.siege.repository.tokens.SiegeWeaponToken; +import mineplex.game.clans.clans.siege.weapon.Cannon; +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.spawn.Spawn; + +public class SiegeManager extends MiniPlugin +{ + public enum Perm implements Permission + { + GIVE_CANNON_COMMAND, + } + + private ClansManager _clansManager; + private OutpostManager _outpostManager; + + public NautHashMap LiveSiegeWeapons = new NautHashMap<>(); + public NautHashMap UnsyncedSiegeWeapons = new NautHashMap<>(); + + private Gson _gson; + + private SiegeWeaponRepository _repository; + + private long _lastDatabaseSave = -1L; + + public SiegeManager(ClansManager clans) + { + super("Siege Manager", clans.getPlugin()); + + _gson = new Gson(); + + _clansManager = clans; + + _outpostManager = new OutpostManager(clans, this); + + _repository = new SiegeWeaponRepository(clans.getPlugin(), this); + + _outpostManager.loadOutposts(); + + getRepository().getWeaponsByServer(getClansManager().getServerId(), tokens -> + tokens.forEach(token -> + runSync(() -> + { + final SiegeWeapon weapon; + + token.Location.getChunk().load(); + + switch(token.WeaponType) + { + case 2: + weapon = new Cannon(SiegeManager.this, token); + break; + default: + System.out.println("[WEAPONS] ERROR WHILST LOADING WEAPON: INVALID WEAPON TYPE"); + return; + } + + System.out.println("[WEAPONS] LOADED SIEGE WEAPON " + weapon.getClass().getSimpleName() + " [" + token.UniqueId + "]"); + + LiveSiegeWeapons.put(token.UniqueId, weapon); + }) + ) + ); + + addCommand(new GiveWeaponCommand(this)); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.GIVE_CANNON_COMMAND, true, true); + } + + @EventHandler + public void CleanupWeirdos(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC && UtilServer.getPlayers().length != 0) + { + Spawn.getSpawnWorld().getEntitiesByClass(Slime.class).stream().filter(slime -> slime.getSize() != -1).forEach(slime -> { + + boolean part = false; + + for (SiegeWeapon weapon : LiveSiegeWeapons.values()) + { + if (weapon.isPartOf(slime.getUniqueId())) + { + part = true; + break; + } + } + + + if (!part) + for (SiegeWeapon weapon : UnsyncedSiegeWeapons.values()) + { + if (weapon.isPartOf(slime.getUniqueId())) + { + part = true; + break; + } + } + + if (!part) + { + System.out.println("Removing slime..."); + slime.remove(); + } + else + { + slime.setSize(-1); + } + }); + } + } + + @EventHandler + public void save(UpdateEvent event) + { + if (!UtilTime.elapsed(_initializedTime, 5500) || UtilServer.getPlayers().length == 0) + { + return; + } + + if (event.getType() == UpdateType.SLOW) + { + if (UtilTime.elapsed(_lastDatabaseSave, 10000)) + { + _lastDatabaseSave = System.currentTimeMillis(); + _outpostManager.saveOutposts(); + saveSiegeWeapons(); + } + + for (Entity entity : Spawn.getSpawnWorld().getEntitiesByClass(ArmorStand.class)) + { + boolean part = false; + + for (SiegeWeapon weapon : LiveSiegeWeapons.values()) + { + if (weapon.isPartOf(entity.getUniqueId())) + { + part = true; + break; + } + } + + if (!part) + for (SiegeWeapon weapon : UnsyncedSiegeWeapons.values()) + { + if (weapon.isPartOf(entity.getUniqueId())) + { + part = true; + break; + } + } + + if (!part) + { + if (((ArmorStand) entity).getHelmet() != null && ((ArmorStand) entity).getHelmet().getType().equals(Material.SPONGE)) + { + System.out.println("Removing armor stand"); + entity.remove(); + } + + if (entity.getPassenger() != null && entity.getPassenger() instanceof Slime && entity.getPassenger().getPassenger() instanceof Slime) + { + System.out.println("Removing armostand + children"); + entity.getPassenger().getPassenger().remove(); + entity.getPassenger().remove(); + entity.remove(); + } + } + } + } + } + + private void saveSiegeWeapons() + { + final Stack queue = new Stack<>(); + + for (final SiegeWeapon weapon : LiveSiegeWeapons.values()) + { + final SiegeWeaponToken token = weapon.toToken(); + + if (UnsyncedSiegeWeapons.containsKey(token.UniqueId)) + continue; + + queue.push(() -> _repository.updateWeapon(token)); + } + + runAsync(() -> { + while (!queue.isEmpty()) + queue.pop().run(); + }); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) + { + if (!Clans.HARDCORE) + { + return; + } + if (event.getItemInHand().isSimilar(Cannon.CANNON_ITEM)) + { + event.setCancelled(true); + + int health = ItemStackFactory.Instance.GetLoreVar(event.getPlayer().getItemInHand(), "Health", 0); + if (health != 0) + { + if (trySpawnCannon(event.getPlayer(), event.getBlock().getLocation())) + { + event.getPlayer().setItemInHand(UtilInv.decrement(event.getPlayer().getItemInHand())); + } + return; + } + + if (trySpawnCannon(event.getPlayer(), event.getBlock().getLocation())) + { + event.getPlayer().setItemInHand(UtilInv.decrement(event.getPlayer().getItemInHand())); + return; + } + } + +// if (event.getItemInHand().isSimilar(Catapult.CATAPULT_ITEM)) +// { +// event.setCancelled(true); +// +// if (trySpawnCatapult(event.getPlayer(), event.getBlock().getLocation())) +// { +// event.getPlayer().setItemInHand(UtilInv.decrement(event.getPlayer().getItemInHand())); +// return; +// } +// } + } + + public boolean trySpawnCannon(Player player, Location location, int health) + { + if (_clansManager.getNetherManager().isInNether(player)) + { + _clansManager.message(player, "You are not allowed to place this in " + F.clansNether("The Nether") + "."); + + return false; + } + if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + _clansManager.message(player, "You are not allowed to place this in a raid."); + + return false; + } + + if (!_clansManager.isInClan(player)) + { + UtilPlayer.message(player, F.main("Clans", "You must be in a Clan to place a Cannon.")); + return false; + } + + if (_clansManager.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot place a Cannon whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + ClanTerritory claim = _clansManager.getClanUtility().getClaim(location); + + if (claim != null && !claim.Owner.equals(_clansManager.getClan(player).getName())) + { + UtilPlayer.message(player, F.main("Clans", "You must place a Cannon in the Wilderness or your own Territory.")); + return false; + } + + spawnCannon(player, location).setHealth(health); + + return true; + } + + public boolean trySpawnCannon(Player player, Location location) + { + if (_clansManager.getNetherManager().isInNether(player)) + { + _clansManager.message(player, "You are not allowed to place this in " + F.clansNether("The Nether") + "."); + + return false; + } + if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + _clansManager.message(player, "You are not allowed to place this in a raid."); + + return false; + } + + if (!_clansManager.isInClan(player)) + { + UtilPlayer.message(player, F.main("Clans", "You must be in a Clan to place a Cannon.")); + return false; + } + + if (_clansManager.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot place a Cannon whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + ClanTerritory claim = _clansManager.getClanUtility().getClaim(location); + + if (claim != null && !claim.Owner.equals(_clansManager.getClan(player).getName())) + { + UtilPlayer.message(player, F.main("Clans", "You must place a Cannon in the Wilderness or your own Territory.")); + return false; + } + + spawnCannon(player, location); + + return true; + } + + public Cannon spawnCannon(Player player, Location location) + { + return spawnCannon(player, location, true); + } + + public Cannon spawnCannon(Player player, Location location, boolean syncWithDb) + { + Cannon cannon = new Cannon(location, _clansManager.getClan(player), this, syncWithDb); + + UnsyncedSiegeWeapons.put(cannon.getUniqueId(), cannon); + + return cannon; + } + + public void dead(SiegeWeapon weapon) + { + LiveSiegeWeapons.remove(weapon.getUniqueId()); + SiegeWeapon unsynced = UnsyncedSiegeWeapons.remove(weapon.getUniqueId()); + + if (unsynced == null) + _repository.deleteWeapon(weapon.getUniqueId()); + } + + public OutpostManager getOutpostManager() + { + return _outpostManager; + } + + public Gson getGson() + { + return _gson; + } + + public ClansManager getClansManager() + { + return _clansManager; + } + + public int randomId() + { + /** + * prevents id from ever being 0 (which is used internally as NULL) + */ + return 1 + UtilMath.random.nextInt(Integer.MAX_VALUE - 1); + } + + public SiegeWeaponRepository getRepository() + { + return _repository; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/command/GiveWeaponCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/command/GiveWeaponCommand.java new file mode 100644 index 00000000..98e58fdc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/command/GiveWeaponCommand.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans.siege.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.siege.SiegeManager; +import mineplex.game.clans.clans.siege.weapon.Cannon; + +public class GiveWeaponCommand extends CommandBase +{ + public GiveWeaponCommand(SiegeManager plugin) + { + super(plugin, SiegeManager.Perm.GIVE_CANNON_COMMAND, "giveweapon", "siegeweapon", "givecannon"); + } + + @Override + public void Execute(Player caller, String[] args) + { + UtilInv.insert(caller, Cannon.CANNON_ITEM.clone()); + UtilPlayer.message(caller, F.main(Plugin.getName(), "You have been given a cannon!")); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/LoadSiegeWeaponEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/LoadSiegeWeaponEvent.java new file mode 100644 index 00000000..92fd2d1e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/LoadSiegeWeaponEvent.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.clans.siege.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; + +public class LoadSiegeWeaponEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private SiegeWeapon _weapon; + + private boolean _cancelled; + + public LoadSiegeWeaponEvent(Player player, SiegeWeapon weapon) + { + _player = player; + _weapon = weapon; + } + + public SiegeWeapon getWeapon() + { + return _weapon; + } + + public Player getPlayer() + { + return _player; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/MountSiegeWeaponEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/MountSiegeWeaponEvent.java new file mode 100644 index 00000000..bf6d4616 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/MountSiegeWeaponEvent.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.clans.siege.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; + +public class MountSiegeWeaponEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private SiegeWeapon _weapon; + + private boolean _cancelled; + + public MountSiegeWeaponEvent(Player player, SiegeWeapon weapon) + { + _player = player; + _weapon = weapon; + } + + public SiegeWeapon getWeapon() + { + return _weapon; + } + + public Player getPlayer() + { + return _player; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/SiegeWeaponExplodeEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/SiegeWeaponExplodeEvent.java new file mode 100644 index 00000000..c0bec7a1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/events/SiegeWeaponExplodeEvent.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.clans.siege.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; +import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile; + +public class SiegeWeaponExplodeEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private SiegeWeapon _weapon; + private WeaponProjectile _projectile; + + private boolean _cancelled; + + public SiegeWeaponExplodeEvent(SiegeWeapon weapon, WeaponProjectile projectile) + { + _weapon = weapon; + _projectile = projectile; + } + + public SiegeWeapon getWeapon() + { + return _weapon; + } + + public WeaponProjectile getProjectile() + { + return _projectile; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java new file mode 100644 index 00000000..3748ff12 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/Outpost.java @@ -0,0 +1,790 @@ +package mineplex.game.clans.clans.siege.outpost; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.Vector; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.ColorFader; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LoopIterator; +import mineplex.core.common.util.RGBData; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilColor; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTrig; +import mineplex.core.hologram.Hologram; +import mineplex.core.hologram.HologramInteraction; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.event.ClansWaterPlaceEvent; +import mineplex.game.clans.clans.event.IronDoorOpenEvent; +import mineplex.game.clans.clans.event.PlayerClaimTerritoryEvent; +import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent; +import mineplex.game.clans.clans.siege.outpost.build.OutpostBlock; +import mineplex.game.clans.clans.siege.repository.tokens.OutpostToken; +import mineplex.game.clans.core.repository.ClanTerritory; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; + +public class Outpost implements Listener +{ + protected static final long MAX_LIFETIME = 45 * 60 * 1000; // 30 minutes + public static final ItemStack OUTPOST_ITEM = new ItemBuilder(Material.BEACON, 1).setRawTitle(C.Reset + C.cBlue + "Outpost").build(); + + public static final long PREP_TIME = 2 * 60 * 1000; + + private static final int MAX_HEALTH = 100; + + private OutpostManager _outpostManager; + + private final int _uniqueId; + + private ClanInfo _ownerClan; + + private Location _startCorner; + private Location _origin; + private Location _endCorner; + + private Location _forceFieldStart; + private Location _forceFieldEnd; + + private Location _core; + + private LinkedHashMap _blocks; + private LinkedHashMap _buildQueue = new LinkedHashMap<>(); + + protected OutpostType _type; + private OutpostState _state; + + private Hologram _preHologram; + private Hologram _preHologram2; + + private LoopIterator _circleStages; + private LoopIterator _reverseCircleStages; + + private ColorFader _fader = new ColorFader(30, UtilColor.hexToRgb(0x00A296), UtilColor.hexToRgb(0x29E6B6)); + + private long _timeSpawned; + + public ClanInfo _againstClan; + + private Hologram _lifetimeLeft; + + private int _health; + + private long _lastDamage; + + private long _lastRegen; + + public Outpost(OutpostManager outpostManager, OutpostToken token) + { + _outpostManager = outpostManager; + + _health = MAX_HEALTH; + + _uniqueId = token.UniqueId; + + _ownerClan = token.OwnerClan; + + _startCorner = token.Origin.clone().subtract(token.Type._size, 1.1, token.Type._size); + _endCorner = token.Origin.clone().add(token.Type._size + .9, token.Type._ySize - 1, token.Type._size + .9); + + _forceFieldStart = _startCorner.clone().subtract(4, 0, 4); + _forceFieldEnd = _endCorner.clone().add(4.5, 0, 4.5); + + _origin = token.Origin.clone(); + + _type = token.Type; + + _timeSpawned = token.TimeSpawned; + + _core = _type.getCoreLocation(_origin); + + _preHologram = new Hologram(outpostManager.getClansManager().getHologramManager(), _origin.clone().add(0.5, 2.3, 0.5), F.elem(_ownerClan.getName()) + C.cWhite + "'s Outpost block (Right-Click to activate)"); + _preHologram2 = new Hologram(outpostManager.getClansManager().getHologramManager(), _origin.clone().add(0.5, 3, 0.5), "Despawning: " + UtilText.getProgress(null, 0, null, true)); + + _lifetimeLeft = new Hologram(outpostManager.getClansManager().getHologramManager(), _origin.clone().add(0.5, 1.5, 0.5), "Despawning in " + F.time(UtilTime.MakeStr(MAX_LIFETIME))); + _lifetimeLeft.setInteraction(new HologramInteraction() + { + public void onClick(Player player, ClickType clickType) + { + if (_ownerClan.isMember(player) || _state != OutpostState.LIVE) + return; + + if (clickType == ClickType.LEFT || clickType == ClickType.SHIFT_LEFT) + { + if (_outpostManager.getClansManager().hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + if (!UtilTime.elapsed(_lastDamage, 5000)) + { + return; + } + if (_health <= 2) + { + UtilPlayer.message(player, F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!")); + + _core.getBlock().setType(Material.AIR); + + _ownerClan.inform("Your Outpost has been destroyed!", null); + UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray()); + + if (getState() == OutpostState.AWAITING) + cleanup(); + else + kill(); + + return; + } + + _lastDamage = System.currentTimeMillis(); + _health -= 2; + } + } + + }); + + + if (token.OutpostState == OutpostState.AWAITING) + { + _preHologram.start(); + _preHologram2.start(); + } + + _blocks = _type.createBuildQueue(_origin, _ownerClan.Clans, _ownerClan); + + _state = token.OutpostState; + + _circleStages = new LoopIterator(UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d)); + + List reverse = UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d); + Collections.reverse(reverse); + _reverseCircleStages = new LoopIterator(reverse); + + } + + public Outpost(OutpostManager outpostManager, ClanInfo clan, Location location, OutpostType type) + { + _outpostManager = outpostManager; + + _health = MAX_HEALTH; + + _uniqueId = outpostManager.getSiegeManager().randomId(); + + _ownerClan = clan; + + _startCorner = location.clone().subtract(type._size, 1.1, type._size); + _endCorner = location.clone().add(type._size + .9, type._ySize - 1, type._size + .9); + + _forceFieldStart = _startCorner.clone().subtract(4, 0, 4); + _forceFieldEnd = _endCorner.clone().add(4.5, 0, 4.5); + + _origin = location.clone(); + + _type = type; + + _timeSpawned = System.currentTimeMillis(); + + _core = _type.getCoreLocation(_origin); + + _preHologram = new Hologram(_ownerClan.Clans.getHologramManager(), _origin.clone().add(0.5, 2.3, 0.5), F.elem(_ownerClan.getName()) + C.cWhite + "'s Outpost block (Right-Click to activate)"); + _preHologram2 = new Hologram(_ownerClan.Clans.getHologramManager(), _origin.clone().add(0.5, 3, 0.5), "Despawning: " + UtilText.getProgress(null, 0, null, true)); + + _preHologram.start(); + _preHologram2.start(); + + _state = OutpostState.AWAITING; + + _outpostManager.getRepository().insertOutpost(toToken()); + + _circleStages = new LoopIterator(UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d)); + + List reverse = UtilTrig.GetCirclePoints(new Vector(0., 0., 0.), 40, .6d); + Collections.reverse(reverse); + _reverseCircleStages = new LoopIterator(reverse); + + UtilServer.RegisterEvents(this); + + _lifetimeLeft = new Hologram(outpostManager.getClansManager().getHologramManager(), _origin.clone().add(0.5, 1.5, 0.5), "Despawning in " + F.time(UtilTime.MakeStr(MAX_LIFETIME))); + _lifetimeLeft.setInteraction(new HologramInteraction() + { + public void onClick(Player player, ClickType clickType) + { + if (_ownerClan.isMember(player) || _state != OutpostState.LIVE) + return; + + if (clickType == ClickType.LEFT || clickType == ClickType.SHIFT_LEFT) + { + if (_outpostManager.getClansManager().hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + if (!UtilTime.elapsed(_lastDamage, 5000)) + { + return; + } + if (_health <= 2) + { + UtilPlayer.message(player, F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!")); + + _core.getBlock().setType(Material.AIR); + + _ownerClan.inform("Your Outpost has been destroyed!", null); + UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray()); + + if (getState() == OutpostState.AWAITING) + { + cleanup(); + } + else + { + kill(); + } + + return; + } + + _lastDamage = System.currentTimeMillis(); + _health -= 2; + } + } + }); + } + + private void cleanup() + { + _blocks = null; + + if (_preHologram != null) _preHologram.stop(); + if (_preHologram2 != null) _preHologram2.stop(); + + _preHologram = null; + _preHologram2 = null; + + _state = OutpostState.DEAD; + + _outpostManager.queueForRemoval(_ownerClan.getName()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInteract(PlayerInteractEvent event) + { + if (getState() == OutpostState.LIVE) + { + if (event.getClickedBlock() == null) + return; + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + + if (!UtilItem.isDoor(event.getClickedBlock().getType())) + return; + + if (_ownerClan.isMember(event.getPlayer())) + return; + + if (UtilAlg.inBoundingBox(event.getClickedBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner)) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot open the doors of this Outpost.")); + event.setCancelled(true); + return; + } + } + + if (getState() != OutpostState.AWAITING) + return; + + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) + return; + + if (getLifetime() <= 2000) + return; + + if (event.getClickedBlock() != null && _origin.equals(event.getClickedBlock().getLocation())) + { + if (event.getClickedBlock().getType().equals(Material.BEACON)) + { + if (_outpostManager.getClansManager().hasTimer(event.getPlayer())) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot activate an Outpost whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + + if (!_ownerClan.equals(_ownerClan.Clans.getClanUtility().getClanByPlayer(event.getPlayer()))) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "This is not yours to activate!")); + return; + } + + for (Block block : UtilBlock.getBlocksInRadius(event.getClickedBlock().getLocation(), 5)) + { + if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot activate an Outpost that close to water!")); + return; + } + if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot activate an Outpost that close to lava!")); + return; + } + } + + _origin.getBlock().setType(Material.AIR); + beginConstruction(); + } + } + } + + @EventHandler + public void onBlockDamage(BlockDamageEvent event) + { + if (event.getBlock().getLocation().equals(_core) && getState() == OutpostState.LIVE) + { + event.setCancelled(true); + if (_outpostManager.getClansManager().hasTimer(event.getPlayer())) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + if (!UtilTime.elapsed(_lastDamage, 5000)) + { + return; + } + if (_health <= 2) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!")); + + _core.getBlock().setType(Material.AIR); + + _ownerClan.inform("Your Outpost has been destroyed!", null); + UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray()); + + if (getState() == OutpostState.AWAITING) + { + cleanup(); + } + else + { + kill(); + } + + return; + } + + _lastDamage = System.currentTimeMillis(); + _health -= 2; + } + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) + { + if (getState() == OutpostState.AWAITING && event.getBlock().getLocation().equals(_origin)) + { + _origin.getBlock().setType(Material.AIR); + _origin.getWorld().dropItem(_origin, OUTPOST_ITEM); + _ownerClan.inform("Your Outpost block has been destroyed.", null); + cleanup(); + event.setCancelled(true); + return; + } + + if (event.getBlock().getLocation().equals(_core) && getState() == OutpostState.LIVE) + { + event.setCancelled(true); + if (_outpostManager.getClansManager().hasTimer(event.getPlayer())) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You cannot destroy an Outpost whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + if (!UtilTime.elapsed(_lastDamage, 5000)) + { + return; + } + if (_health <= 2) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have destroyed " + F.elem(_ownerClan.getName()) + "'s Outpost!")); + + _core.getBlock().setType(Material.AIR); + + _ownerClan.inform("Your Outpost has been destroyed!", null); + UtilTextMiddle.display("Siege", "Your Outpost has been destroyed", 20, 100, 20, _ownerClan.getOnlinePlayersArray()); + + if (getState() == OutpostState.AWAITING) + { + cleanup(); + } + else + { + kill(); + } + + return; + } + + _lastDamage = System.currentTimeMillis(); + _health -= 2; + } + + if (UtilAlg.inBoundingBox(event.getBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner)) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You may not break blocks in Outposts.")); + event.setCancelled(true); + } + } + + @EventHandler + public void onWaterPlace(ClansWaterPlaceEvent event) + { + if (UtilAlg.inBoundingBox(event.getBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner)) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You may not place water in Outposts.")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onBlockPlace(BlockPlaceEvent event) + { + if (event.isCancelled()) + return; + + if (UtilAlg.inBoundingBox(event.getBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner)) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You may not place blocks in Outposts.")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void claimTerritory(PlayerClaimTerritoryEvent event) + { + if (UtilMath.offset2d(event.getClaimedChunk().getBlock(8, 0, 8).getLocation(), _origin) < 32) + { + UtilPlayer.message(event.getClaimer(), F.main("Clans", "You may not claim this close to an Outpost.")); + event.setCancelled(true); + } + } + + protected void update() + { + if (_state == OutpostState.AWAITING) + { + if (getLifetime() > 60000) + { + _origin.getBlock().setType(Material.AIR); + _ownerClan.inform("You have lost your Outpost block, as no one activated it fast enough!", null); + cleanup(); + return; + } + + _preHologram2.setText(UtilText.getProgress(null, UtilMath.clamp(getLifetime(), 0., 60000.) / 60000., null, true)); + + RGBData color = UtilColor.RgbLightBlue; + + for (int x = -_type._size; x <= _type._size; x++) + for (int z = -_type._size; z <= _type._size; z++) + if (x == -_type._size || x == _type._size || z == -_type._size || z == _type._size) + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, UtilBlock.getHighest(_origin.getWorld(), _origin.clone().add(x + .5, .1, z + .5).getBlockX(), _origin.clone().add(x + .5, .1, z + .5).getBlockZ()).getLocation().add(0.5, 0, 0.5), new Vector(color.getRed(), color.getGreen(), color.getBlue()), 1f, 0, ViewDist.NORMAL); + + return; + } + + if (_lifetimeLeft != null) + { + _lifetimeLeft.setText("Health: " + _health, "Despawning in " + F.time(UtilTime.MakeStr(MAX_LIFETIME - (System.currentTimeMillis() - _timeSpawned)))); + } + + if (_state == OutpostState.CONSTRUCTING) + { + if (_buildQueue.isEmpty()) + { + _state = OutpostState.LIVE; + + return; + } + else + { + Iterator iterator = _buildQueue.keySet().iterator(); + + if (iterator.hasNext()) + _buildQueue.remove(iterator.next()).set(); + } + + // Forcefield + RGBData color = UtilColor.RgbLightBlue; + + for (int x = _forceFieldStart.getBlockX(); x <= _forceFieldEnd.getBlockX(); x++) + for (int z = _forceFieldStart.getBlockZ(); z <= _forceFieldEnd.getBlockZ(); z++) + if (x == _forceFieldStart.getBlockX() || x == _forceFieldEnd.getBlockX() || z == _forceFieldStart.getBlockZ() || z == _forceFieldEnd.getBlockZ()) + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, new Location(_core.getWorld(), x + .5, UtilBlock.getHighest(_core.getWorld(), x, z).getY() + .15, z + .5), new Vector(color.getRed(), color.getGreen(), color.getBlue()), 1f, 0, ViewDist.NORMAL); + } + + RGBData next = _fader.next(); + + { + RGBData color = _state == OutpostState.LIVE ? next : UtilColor.RgbRed; + + Vector nextCircleStage = _circleStages.next(); + + double circleX = nextCircleStage.getX(); + double circleZ = nextCircleStage.getZ(); + + UtilParticle.PlayParticleToAll(ParticleType.MOB_SPELL, _core.clone().add(circleX + .5, 1.1d, circleZ + .5), new Vector(color.getRed(), color.getGreen(), color.getBlue()), 1.f, 0, ViewDist.NORMAL); + } + + { + RGBData color = _state == OutpostState.LIVE ? next : UtilColor.RgbRed; + + Vector nextCircleStage = _reverseCircleStages.next(); + + double circleX = nextCircleStage.getX(); + double circleZ = nextCircleStage.getZ(); + + UtilParticle.PlayParticleToAll(ParticleType.MOB_SPELL, _core.clone().add(circleX + .5, 1.1d, circleZ + .5), new Vector(color.getRed(), color.getGreen(), color.getBlue()), 1.f, 0, ViewDist.NORMAL); + } + + if (_state == OutpostState.LIVE) + { + if (UtilTime.elapsed(_timeSpawned, MAX_LIFETIME)) + { + kill(); + } + if (_health < MAX_HEALTH && UtilTime.elapsed(_lastDamage, 15000) && UtilTime.elapsed(_lastRegen, 1000)) + { + _lastRegen = System.currentTimeMillis(); + _health++; + } + } + } + + @EventHandler + public void forcefield(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST || getState() != OutpostState.CONSTRUCTING) + return; + + UtilServer.getPlayersCollection().stream() + .filter(player -> !_ownerClan.isMember(player)) + .filter(player -> UtilAlg.inBoundingBox(player.getLocation(), _forceFieldStart, _forceFieldEnd)) + .forEach(player -> { + UtilAction.velocity(player, UtilAlg.getTrajectory2d(_core, player.getLocation()), .77, true, 0.8, 0, 1.1, true); + UtilPlayer.message(player, F.main("Clans", "This Outpost is still under construction!")); + player.playSound(player.getLocation(), Sound.NOTE_BASS, 1.0f, 1.0f); + }); + } + + public void beginConstruction() + { + // Cleanup pre-Outpost stuff + _preHologram.stop(); + _preHologram2.stop(); + + _preHologram = null; + _preHologram = null; + + _lifetimeLeft.start(); + + _state = OutpostState.CONSTRUCTING; + _blocks = new LinkedHashMap<>(_buildQueue = _type.createBuildQueue(_origin, _ownerClan.Clans, _ownerClan)); + + _ownerClan.inform("Siege", "Your Outpost is now being constructed.", null); + + //Inform nearby Clans + for (int chunkX = -3; chunkX < 3; chunkX++) + { + for (int chunkZ = -3; chunkZ < 3; chunkZ++) + { + ClanTerritory territory = _ownerClan.Clans.getClanUtility().getClaim(_origin.getWorld().getChunkAt(_origin.getChunk().getX() + chunkX, _origin.getChunk().getZ() + chunkZ)); + + if (territory != null && _outpostManager.getClansManager().getBlacklist().allowed(territory.Owner)) + { + ClanInfo clan = _ownerClan.Clans.getClanUtility().getClanByClanName(territory.Owner); + + clan.inform("A siege has begun near your territory!", null); + UtilTextMiddle.display("Siege", "A Siege has been declared on your Clan!", 20, 100, 20, clan.getOnlinePlayersArray()); + } + } + } + } + + public void kill() + { + _state = OutpostState.DESTRUCTING; + + EnclosedObject wait = new EnclosedObject<>(0); + + _blocks.values().stream().filter(block -> UtilMath.random.nextBoolean() && UtilMath.random.nextBoolean()).filter(block -> UtilMath.random.nextBoolean()).limit(13).forEach(block -> + _outpostManager.runSyncLater(() -> + { + UtilParticle.PlayParticleToAll(ParticleType.HUGE_EXPLOSION, block.getLocation(), new Vector(0,0,0), 1f, 1, ViewDist.MAX); + _origin.getWorld().playSound(block.getLocation(), Sound.EXPLODE, 1.0f, 1.0f); + }, wait.Set(wait.Get() + 4 + UtilMath.random.nextInt(4))) + ); + + _outpostManager.runSyncLater(() -> + { + _blocks.values().stream().forEach(OutpostBlock::restore); + }, wait.Get() + 5L); + + _outpostManager.runSyncLater(() -> + { + _blocks.values().stream().forEach(block -> + { + Material mat = Material.getMaterial(block.getId()); + + if (UtilItem.isTranslucent(mat) || UtilMath.random.nextBoolean()) + { + block.restore(); + return; + } + + FallingBlock fall = block.getLocation().getWorld().spawnFallingBlock(block.getLocation(), block.getId(), block.getData()); + fall.setDropItem(false); + Vector vec = UtilAlg.getTrajectory(fall.getLocation(), getExactMiddle()); + + UtilAction.velocity(fall, vec, 1, false, 0, 0.6, 10, false); + + fall.setMetadata("ClansOutpost", new FixedMetadataValue(_ownerClan.Clans.getPlugin(), _ownerClan.getName())); + + block.restore(); + }); + + cleanup(); + }, wait.Get() + 6L); + + if (_lifetimeLeft != null) _lifetimeLeft.stop(); + + _lifetimeLeft = null; + + _ownerClan.inform("Your Clan's Outpost has been destroyed.", null); + } + + @EventHandler + public void doorOpen(IronDoorOpenEvent event) + { + if (!UtilAlg.inBoundingBox(event.getBlock().getLocation(), _startCorner.clone().subtract(.5, 0, .5), _endCorner)) + { + return; + } + + if (_ownerClan.isMember(event.getPlayer())) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void onSiegeWeaponExplode(SiegeWeaponExplodeEvent event) + { + if (UtilAlg.inBoundingBox(event.getProjectile().getLocation(), _startCorner.clone().subtract(2, 2, 2), _endCorner.clone().add(2, 2, 2))) + { + if (getLifetime() < 15 * 60 * 1000) + { + event.setCancelled(true); + } + } + } + + public ClanInfo getOwner() + { + return _ownerClan; + } + + public long getLifetime() + { + return System.currentTimeMillis() - _timeSpawned; + } + + public AxisAlignedBB getBounds() + { + return UtilAlg.toBoundingBox(_startCorner, _endCorner); + } + + public Pair getBoundsBlockBreak() + { + return Pair.create(_startCorner.clone().subtract(0.5, 0, 0.5), _endCorner.clone()); + } + + public Location getExactMiddle() + { + return UtilAlg.getMidpoint(_startCorner, _endCorner); + } + + public OutpostState getState() + { + return _state; + } + + public ClanInfo getAgainst() + { + return _againstClan; + } + + public int getUniqueId() + { + return _uniqueId; + } + + public OutpostToken toToken() + { + OutpostToken token = new OutpostToken(); + + token.UniqueId = _uniqueId; + token.Origin = _origin; + token.Type = _type; + token.OwnerClan = _ownerClan; + token.TimeSpawned = _timeSpawned; + token.OutpostState = _state; + + return token; + } + + public Location getCoreLocation() + { + return _core; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostManager.java new file mode 100644 index 00000000..1297916f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostManager.java @@ -0,0 +1,341 @@ +package mineplex.game.clans.clans.siege.outpost; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; + +import com.google.common.collect.Lists; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.PlayerClaimTerritoryEvent; +import mineplex.game.clans.clans.siege.SiegeManager; +import mineplex.game.clans.clans.siege.repository.OutpostRepository; +import mineplex.game.clans.clans.siege.repository.tokens.OutpostToken; +import mineplex.game.clans.core.repository.ClanTerritory; + +public class OutpostManager extends MiniPlugin +{ + private ClansManager _clansManager; + + private NautHashMap _outposts = new NautHashMap<>(); + private NautHashMap _idToOutpost = new NautHashMap<>(); + + private List _removalQueue; + + private SiegeManager _siegeManager; + + private OutpostRepository _repository; + + public OutpostManager(ClansManager clansManager, SiegeManager siegeManager) + { + super("Outpost Manager", clansManager.getPlugin()); + + _siegeManager = siegeManager; + + _clansManager = clansManager; + + _repository = new OutpostRepository(clansManager.getPlugin(), this); + + _removalQueue = new ArrayList<>(); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlaceBlock(BlockPlaceEvent event) + { + if (!Clans.HARDCORE) + { + return; + } + if (event.getItemInHand().isSimilar(Outpost.OUTPOST_ITEM)) + if (!spawnOutpost(event.getPlayer(), event.getBlock().getLocation(), OutpostType.MK_III)) + event.setCancelled(true); + } + + public boolean spawnOutpost(Player player, Location location, OutpostType type) + { + if (_clansManager.getNetherManager().isInNether(player)) + { + _clansManager.message(player, "You are not allowed to place this in " + F.clansNether("The Nether") + "."); + + return false; + } + + if (_clansManager.getWorldEvent().getRaidManager().isInRaid(player.getLocation())) + { + _clansManager.message(player, "You are not allowed to place this in a raid."); + + return false; + } + + if (!_clansManager.isInClan(player)) + { + UtilPlayer.message(player, F.main("Clans", "You must be in a Clan to place an Outpost.")); + return false; + } + + if (_clansManager.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You can't place an Outpost whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + if (location.getBlockY() < 30) + { + UtilPlayer.message(player, F.main("Clans", "You cannot place an Outpost this deep.")); + return false; + } + + ClanInfo clan = _clansManager.getClan(player); + + if (UtilItem.isBoundless(location.clone().subtract(0, 1, 0).getBlock().getType())) + { + UtilPlayer.message(player, F.main("Clans", "An Outpost must not be placed floating.")); + return false; + } + + if (Get(clan) != null) + { + UtilPlayer.message(player, F.main("Clans", "Your Clan already has an outpost.")); + return false; + } + + if (_clansManager.getClanUtility().getClaim(location) != null) + { + UtilPlayer.message(player, F.main("Clans", "An Outpost must be placed in the Wilderness.")); + return false; + } + + for (Outpost outpost : _outposts.values()) + { + if (UtilMath.offset(location, outpost.getExactMiddle()) < type._size + 8) + { + UtilPlayer.message(player, F.main("Clans", "You cannot place an Outpost near other Outposts.")); + return false; + } + } + + for (int x = -2; x < 2; x++) + { + for (int z = -2; z < 2; z++) + { + Chunk chunk = location.getWorld().getChunkAt(location.getChunk().getX() + x, location.getChunk().getZ() + z); + + ClanTerritory claim = _clansManager.getClanUtility().getClaim(chunk); + + if (claim != null) + { + if (!claim.Owner.equals(clan.getName()) && _clansManager.getBlacklist().allowed(claim.Owner)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot place an Outpost this close to a Clan's Territory.")); + return false; + } + } + } + } + + boolean gut = false; + + for (int x = -6; x < 6; x++) + { + for (int z = -6; z < 6; z++) + { + Chunk chunk = location.getWorld().getChunkAt(location.getChunk().getX() + x, location.getChunk().getZ() + z); + + ClanTerritory claim = _clansManager.getClanUtility().getClaim(chunk); + + if (claim != null) + { + System.out.println(claim.Owner + ", " + clan.getName()); + + if (!claim.Owner.equals(clan.getName()) && _clansManager.getBlacklist().allowed(claim.Owner)) + { + gut = true; /* das ist gut!!! */ + break; + } + } + } + } + + /* das ist schlecht */ + if (!gut) + { + UtilPlayer.message(player, F.main("Clans", "An Outpost must be placed near a rival Clan's Territory.")); + return false; + } + + for (int x = -type._size; x < type._size; x++) + { + for (int y = -1; y < type._ySize; y++) + { + for (int z = -type._size; z < type._size; z++) + { + Location loc = location.clone().add(x, y, z); + + if (_clansManager.getClanUtility().isClaimed(loc)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot place an Outpost where it may intersect with claimed territory.")); + return false; + } + } + } + } + + _outposts.put(clan.getName(), new Outpost(this, clan, location, type)); + _idToOutpost.put(_outposts.get(clan.getName()).getUniqueId(), _outposts.get(clan.getName())); + + return true; + } + + @EventHandler + public void onBlockFall(EntityChangeBlockEvent event) + { + if (event.getEntity().hasMetadata("ClansOutpost")) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onClaim(PlayerClaimTerritoryEvent event) + { + for (Outpost outpost : _outposts.values()) + { + if (outpost.getBounds().b(UtilAlg.toBoundingBox(event.getClaimedChunk().getBlock(0, 0, 0).getLocation(), event.getClaimedChunk().getBlock(15, 254, 15).getLocation()))) + { + event.setCancelled(true); + UtilPlayer.message(event.getClaimer(), F.main("Clans", "You cannot claim this territory as it overlaps with " + F.elem(outpost.getOwner().getName()) + "'s Outpost.")); + break; + } + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.TICK) + _outposts.values() + .stream() + .forEach(Outpost::update); + + if (event.getType() == UpdateType.FASTER) + if (!_removalQueue.isEmpty()) + HandlerList.unregisterAll(_idToOutpost.remove(_outposts.remove(_removalQueue.remove(0)).getUniqueId())); + + if (event.getType() == UpdateType.TWOSEC) + _outposts.values() + .stream() + .filter(outpost -> outpost.getState() == OutpostState.LIVE && outpost.getLifetime() > Outpost.MAX_LIFETIME) + .forEach(Outpost::kill); + } + + public Outpost Get(ClanInfo clan) + { + return clan == null ? null : _outposts.get(clan.getName()); + } + + public void queueForRemoval(String name) + { + _removalQueue.add(name); + } + + public SiegeManager getSiegeManager() + { + return _siegeManager; + } + + public List getOutposts() + { + return Lists.newArrayList(_outposts.values()); + } + + public Outpost Get(int outpostId) + { + return _idToOutpost.get(outpostId); + } + + public ClansManager getClansManager() + { + return _clansManager; + } + + public void loadOutposts() + { + System.out.println("[OUTPOSTS] LOADING OUTPOSTS FROM DATABASE"); + + _repository.getOutpostsByServer(_clansManager.getServerId(), tokens -> + tokens.forEach(token -> + { + Outpost outpost = new Outpost(this, token); + + if ((System.currentTimeMillis() - token.TimeSpawned) > Outpost.MAX_LIFETIME) + { + System.out.println("[OUTPOSTS] SKIPPING & REMOVING OUTPOST [" + token.UniqueId + "] BECAUSE OF OLD AGE"); + + _repository.deleteOutpost(token.UniqueId); + outpost.kill(); + + return; + } + + System.out.println("[OUTPOSTS] INITIALIZED OUTPOST FROM DATABASE SAVE"); + + _outposts.put(token.OwnerClan.getName(), outpost); + }) + ); + } + + public void saveOutposts() + { + final Stack queue = new Stack<>(); + + _outposts.values().forEach(outpost -> + { + final OutpostToken token = outpost.toToken(); + + queue.push(() -> _repository.updateOutpost(token)); + }); + + runAsync(() -> + { + while (!queue.isEmpty()) + queue.pop().run(); + + _repository.getOutpostsByServer(_clansManager.getServerId(), tokens -> + { + tokens.forEach(token -> + { + if (!_idToOutpost.containsKey(token.UniqueId)) + { + System.out.println("[OUTPOSTS] OUTPOST [" + token.UniqueId + "] NO LONGER EXISTS, DELETING"); + _repository.deleteOutpost(token.UniqueId); + } + }); + }); + }); + } + + public OutpostRepository getRepository() + { + return _repository; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostState.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostState.java new file mode 100644 index 00000000..8d37671f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostState.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.clans.siege.outpost; + +public enum OutpostState +{ + /** + * this much space between them so that there is some room for any potential new states. + */ + AWAITING(10), + CONSTRUCTING(20), + LIVE(30), + DESTRUCTING(40), + DEAD(50); + + private byte _id; + + OutpostState(int id) + { + _id = (byte) id; + } + + public static OutpostState ById(byte id) + { + for (OutpostState state : values()) + { + if (state._id == id) + { + return state; + } + } + + return null; + } + + public byte getId() + { + return _id; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostType.java new file mode 100644 index 00000000..c14bc04d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/OutpostType.java @@ -0,0 +1,406 @@ +package mineplex.game.clans.clans.siege.outpost; + +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Objects; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.banner.Pattern; + +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.UtilSchematic; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.banners.BannerManager; +import mineplex.game.clans.clans.banners.BannerPattern; +import mineplex.game.clans.clans.banners.ClanBanner; +import mineplex.game.clans.clans.siege.outpost.build.OutpostBlock; +import mineplex.game.clans.clans.siege.outpost.build.OutpostBlockBanner; + +public enum OutpostType +{ + MK_I(1, 3, 6) { + public LinkedHashMap createBuildQueue(Location location, ClansManager clans, ClanInfo owner) + { + LinkedHashMap build = new LinkedHashMap<>(); + + for (int y = -1; y <= _ySize; y++) + { + for (int x = -_size; x <= _size; x++) + { + for (int z = -_size; z <= _size; z++) + { + Location loc = new Location(location.getWorld(), location.getX()+x, location.getY()+y, location.getZ()+z); + + if (clans.getClanUtility().isClaimed(loc)) + { + continue; + } + + boolean added = false; + + //Floor + if (y == -1 && Math.abs(x) <= _size-1 && Math.abs(z) <= _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 98, (byte)0)); + added = true; + } + + //Walls + if (Math.abs(x) == _size || Math.abs(z) == _size) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 98, (byte)0)); + added = true; + } + + //Roof + if (y == 5 && Math.abs(x) <= _size-1 && Math.abs(z) <= _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 44, (byte)13)); + added = true; + } + + //Clear + if (!added) + { + if (loc.getBlock().getTypeId() != 0) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 0, (byte) 0)); + } + } + } + } + } + + for (int y= -1; y <= _ySize; y++) + { + for (int x = -_size; x <= _size; x++) + { + for (int z = -_size; z <= _size; z++) + { + Location loc = new Location(location.getWorld(), location.getX()+x, location.getY()+y, location.getZ()+z); + + if (clans.getClanUtility().isClaimed(loc)) + { + continue; + } + + //Doors + if (y == 0 || y == 1) + { + if (x == 0 && z == _size) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 71, (byte)(y * 8 + 2 + 4))); + } + + if (x == 0 && z == -_size) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 71, (byte)(y * 8 + 4))); + } + + if (x == _size && z == 0) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 71, (byte)(y * 8 + 3 + 4))); + } + + if (x == -_size && z == 0) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 71, (byte)(y * 8 + 1 + 4))); + } + } + + //Platform + if (y == 2) + { + if (Math.abs(x) == _size-1 && Math.abs(z) < _size) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 44, (byte)13)); + } + + if (Math.abs(z) == _size-1 && Math.abs(x) < _size) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 44, (byte)13)); + } + } + + //Windows + if (y == 4) + { + if (Math.abs(x) == _size && Math.abs(z) < _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 0, (byte)0)); + } + + if (Math.abs(z) == _size && Math.abs(x) < _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 0, (byte)0)); + } + } + + //Ladders + if (y >= 0 && y < 3) + { + if (x == _size-1 && z == _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 65, (byte)2)); + } + + if (x == (-_size)+1 && z == (-_size)+1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 65, (byte)3)); + } + } + + //Chests + if (y == 0) + { + if (x == _size-1 && z == (-_size)+1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 54, (byte)0)); + } + + if (x == (-_size)+1 && z == _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 54, (byte)0)); + } + + if (x == _size-2 && z == (-_size)+1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 54, (byte)0)); + } + + if (x == (-_size)+2 && z == _size-1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 54, (byte)0)); + } + } + + //Beacon Floor + if (y == -1) + { + if (Math.abs(x) <= 1 && Math.abs(z) <= 1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 42, (byte)0)); + } + } + + //Beacon Roof + if (y == 5) + { + if (Math.abs(x) == 1 && Math.abs(z) <= 1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 98, (byte)0)); + } + + if (Math.abs(z) == 1 && Math.abs(x) <= 1) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 98, (byte)0)); + } + } + + //Beacon Glass + if (y == 5 && x == 0 && z == 0) + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, 20, (byte)0)); + } + } + } + } + + //Core + build.put(UtilWorld.locToStr(getCoreLocation(location)), new OutpostBlock(build, getCoreLocation(location), Material.DIAMOND_BLOCK.getId(), (byte)0)); + + return build; + } + + public List getWallLocations(Location middle) + { + List list = new ArrayList<>(); + + list.add(middle.clone().add(_size / 2, 0, 0).add(1, 0, 0)); + list.add(middle.clone().add(_size / 2, 0, -(_size / 2)).add(1, 0, -1)); + list.add(middle.clone().add(-(_size / 2), 0, -(_size / 2)).add(-1, 0, -1)); + list.add(middle.clone().add(-(_size / 2), 0, 0).add(-1, 0, 0)); + + return list; + } + + public Location getCoreLocation(Location location) + { + return location.clone().subtract(0, 1, 0); + } + }, + MK_II(2, 5, 25) { + public LinkedHashMap createBuildQueue(Location location, ClansManager clans, ClanInfo owner) + { + try + { + LinkedHashMap build = new LinkedHashMap<>(); + + File file = new File("schematic" + File.separator + "outpost_mk_II.schematic"); + Schematic schematic = UtilSchematic.loadSchematic(file); + + for (int y = 0; y < schematic.getHeight(); y++) + { + for (int x = 0; x < schematic.getWidth(); x++) + { + for (int z = 0; z < schematic.getLength(); z++) + { + int relativeX = -(schematic.getWidth() / 2) + x; + int relativeZ = -(schematic.getLength() / 2) + z; + + Location loc = location.clone().add(relativeX, y - 1, relativeZ); + + if (schematic.getBlock(x, y, z) == 0 && loc.getBlock().getType() == Material.AIR) + { + continue; + } + + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z))); + } + } + } + + //Core + build.put(UtilWorld.locToStr(getCoreLocation(location)), new OutpostBlock(build, getCoreLocation(location), Material.DIAMOND_BLOCK.getId(), (byte)0)); + + return build; + } + catch(Exception e) + { + e.printStackTrace(); + return null; + } + } + + public List getWallLocations(Location middle) + { + List list = new ArrayList<>(); + + list.add(middle.clone().add(_size / 2, 0, 0).add(1, 0, 0)); + list.add(middle.clone().add(_size / 2, 0, -(_size / 2)).add(1, 0, -1)); + list.add(middle.clone().add(-(_size / 2), 0, -(_size / 2)).add(-1, 0, -1)); + list.add(middle.clone().add(-(_size / 2), 0, 0).add(-1, 0, 0)); + + return list; + } + + public Location getCoreLocation(Location location) + { + return location.clone().subtract(0, 1, 0); + } + }, + MK_III(3, 5, 25) { + public LinkedHashMap createBuildQueue(Location location, ClansManager clans, ClanInfo owner) + { + try + { + LinkedHashMap build = new LinkedHashMap<>(); + + File file = new File("schematic" + File.separator + "outpost_mk_III.schematic"); + Schematic schematic = UtilSchematic.loadSchematic(file); + BannerManager bm = clans.getBannerManager(); + ClanBanner cb = bm.LoadedBanners.get(owner.getName()); + + for (int y = 0; y < schematic.getHeight(); y++) + { + for (int x = 0; x < schematic.getWidth(); x++) + { + for (int z = 0; z < schematic.getLength(); z++) + { + int relativeX = -(schematic.getWidth() / 2) + x; + int relativeZ = -(schematic.getLength() / 2) + z; + + Location loc = location.clone().add(relativeX, y - 1, relativeZ); + + if (schematic.getBlock(x, y, z) == 0 && loc.getBlock().getType() == Material.AIR) + { + continue; + } + + if (Material.getMaterial(schematic.getBlock(x, y, z)).name().contains("BANNER")) + { + if (cb == null) + { + continue; + } + build.put(UtilWorld.locToStr(loc), new OutpostBlockBanner(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z), cb.getBaseColor(), cb.getPatterns().stream().map(BannerPattern::getBukkitPattern).filter(Objects::nonNull).toArray(size -> new Pattern[size]))); + } + else + { + build.put(UtilWorld.locToStr(loc), new OutpostBlock(build, loc, schematic.getBlock(x, y, z), schematic.getData(x, y, z))); + } + } + } + } + + //Core + build.put(UtilWorld.locToStr(getCoreLocation(location)), new OutpostBlock(build, getCoreLocation(location), Material.DIAMOND_BLOCK.getId(), (byte)0)); + + return build; + } + catch(Exception e) + { + e.printStackTrace(); + return null; + } + } + + public List getWallLocations(Location middle) + { + List list = new ArrayList<>(); + + list.add(middle.clone().add(_size / 2, 0, 0).add(1, 0, 0)); + list.add(middle.clone().add(_size / 2, 0, -(_size / 2)).add(1, 0, -1)); + list.add(middle.clone().add(-(_size / 2), 0, -(_size / 2)).add(-1, 0, -1)); + list.add(middle.clone().add(-(_size / 2), 0, 0).add(-1, 0, 0)); + + return list; + } + + public Location getCoreLocation(Location location) + { + return location.clone().subtract(0, 1, 0); + } + }; + + protected int _size; + protected int _ySize; + + private int _id; + + OutpostType(int id, int size, int ySize) + { + _size = size; + _ySize = ySize; + _id = id; + } + + public int getId() + { + return _id; + } + + public abstract LinkedHashMap createBuildQueue(Location location, ClansManager clans, ClanInfo owner); + + public abstract Location getCoreLocation(Location location); + + public abstract List getWallLocations(Location location); + + public static OutpostType ById(byte id) + { + for (OutpostType type : values()) + { + if (type._id == id) + { + return type; + } + } + + return null; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/build/OutpostBlock.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/build/OutpostBlock.java new file mode 100644 index 00000000..c0f2f490 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/build/OutpostBlock.java @@ -0,0 +1,82 @@ +package mineplex.game.clans.clans.siege.outpost.build; + +import java.util.Map; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockState; + +import mineplex.core.common.util.UtilWorld; + +public class OutpostBlock +{ + private Location _location; + private int _id; + private byte _data; + + private int _originalId; + private byte _originalData; + + public OutpostBlock(Map blocks, Location loc, int id, byte data) + { + _location = loc; + _id = id; + _data = data; + + String locStr = UtilWorld.locToStr(loc); + + if (blocks.containsKey(locStr)) + { + _originalId = blocks.get(locStr)._originalId; + _originalData = blocks.get(locStr)._originalData; + } + else + { + _originalId = _location.getBlock().getTypeId(); + _originalData = _location.getBlock().getData(); + } + } + + public void set() + { + _location.getBlock().setTypeIdAndData(_id, _data, false); + if (_id != 0) + { + _location.getWorld().playEffect(_location, Effect.STEP_SOUND, Material.getMaterial(_id), 10); + } + } + + public void restore() + { + BlockState state = _location.getBlock().getState(); + state.setTypeId(_originalId); + state.setRawData(_originalData); + state.update(true, false); + } + + public int getId() + { + return _id; + } + + public byte getData() + { + return _data; + } + + public int getOriginalId() + { + return _originalId; + } + + public int getOriginalData() + { + return _originalData; + } + + public Location getLocation() + { + return _location; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/build/OutpostBlockBanner.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/build/OutpostBlockBanner.java new file mode 100644 index 00000000..02ec95e8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/outpost/build/OutpostBlockBanner.java @@ -0,0 +1,40 @@ +package mineplex.game.clans.clans.siege.outpost.build; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.block.Banner; +import org.bukkit.block.banner.Pattern; + +/** + * Special block for Mk III Outpost + * + */ +public class OutpostBlockBanner extends OutpostBlock +{ + private DyeColor _baseColor; + private List _patterns; + + public OutpostBlockBanner(Map blocks, Location loc, int id, byte data, DyeColor color, Pattern... patterns) + { + super(blocks, loc, id, data); + _baseColor = color; + _patterns = new ArrayList<>(Arrays.asList(patterns)); + } + + @Override + public void set() + { + super.set(); + + Banner banner = (Banner) getLocation().getBlock().getState(); + banner.setBaseColor(_baseColor); + banner.setPatterns(_patterns); + + banner.update(true, false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/OutpostRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/OutpostRepository.java new file mode 100644 index 00000000..6fe2d021 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/OutpostRepository.java @@ -0,0 +1,137 @@ +package mineplex.game.clans.clans.siege.repository; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.List; + +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.database.MinecraftRepository; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.siege.outpost.OutpostManager; +import mineplex.game.clans.clans.siege.outpost.OutpostState; +import mineplex.game.clans.clans.siege.outpost.OutpostType; +import mineplex.game.clans.clans.siege.repository.tokens.OutpostToken; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnByte; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnTimestamp; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class OutpostRepository extends RepositoryBase +{ + private OutpostManager _manager; + + private static final String CREATE = "CREATE TABLE IF NOT EXISTS clansOutposts (uniqueId INT NOT NULL," + + "serverId INT NOT NULL," + + "origin VARCHAR(30)," + + "outpostType TINYINT NOT NULL," + + "ownerClan INT NOT NULL," + + "timeSpawned LONG," + + "outpostState TINYINT NOT NULL," + + "PRIMARY KEY (uniqueId));"; + + private static final String GET_OUTPOST_BY_ID = "SELECT * FROM clansOutposts WHERE uniqueId=?;"; + private static final String GET_OUTPOST_BY_CLAN = "SELECT * FROM clansOutposts WHERE ownerClan=?;"; + private static final String GET_OUTPOSTS_BY_SERVER = "SELECT * FROM clansOutposts WHERE serverId=?;"; + + private static final String UPDATE_OUTPOST = "UPDATE clansOutposts SET outpostState=? WHERE uniqueId=?;"; + private static final String INSERT_OUTPOST = "INSERT INTO clansOutposts VALUES (?, ?, ?, ?, ?, ?, ?);"; + + private static final String DELETE_OUTPOST = "DELETE FROM clansOutposts WHERE uniqueId=?;"; + + public OutpostRepository(JavaPlugin plugin, OutpostManager manager) + { + super(DBPool.getAccount()); + + _manager = manager; + } + + public void deleteOutpost(final int uniqueId) + { + executeUpdate(DELETE_OUTPOST, new ColumnInt("uniqueId", uniqueId)); + } + + public void getOutpostById(final int uniqueId, final Callback callback) + { + executeQuery(GET_OUTPOST_BY_ID, resultSet -> { + OutpostToken token = new OutpostToken(); + + resultSet.next(); + + load(token, resultSet); + + callback.run(token); + }, new ColumnInt("uniqueId", uniqueId)); + } + + public void getOutpostByClan(final ClanInfo clan, final Callback callback) + { + executeQuery(GET_OUTPOST_BY_CLAN, resultSet -> { + resultSet.next(); + + OutpostToken token = new OutpostToken(); + + load(token, resultSet); + + callback.run(token); + }, new ColumnInt("ownerClan", clan.getId())); + } + + public void getOutpostsByServer(final int serverId, final Callback> callback) + { + executeQuery(GET_OUTPOSTS_BY_SERVER, resultSet -> { + List tokens = Lists.newArrayList(); + + while (resultSet.next()) + { + OutpostToken token = new OutpostToken(); + load(token, resultSet); + tokens.add(token); + } + + callback.run(tokens); + }, new ColumnInt("serverId", serverId)); + } + + private void load(OutpostToken token, ResultSet columns) throws SQLException + { + token.UniqueId = columns.getInt("uniqueId"); + token.Origin = UtilWorld.strToLoc(columns.getString("origin")); + token.Type = OutpostType.ById(columns.getByte("outpostType")); + token.OwnerClan = _manager.getClansManager().getClanUtility().getClanById(columns.getInt("ownerClan")); + token.TimeSpawned = columns.getTimestamp("timeSpawned").getTime(); + token.OutpostState = OutpostState.ById(columns.getByte("outpostState")); + } + + @Override + protected void initialize() + { + executeUpdate(CREATE); + } + + public void updateOutpost(OutpostToken token) + { + executeUpdate(UPDATE_OUTPOST, + new ColumnByte("outpostState", token.OutpostState.getId()), + new ColumnInt("uniqueId", token.UniqueId)); + } + + public void insertOutpost(OutpostToken token) + { + executeUpdate(INSERT_OUTPOST, + new ColumnInt("uniqueId", token.UniqueId), + new ColumnInt("serverId", _manager.getClansManager().getServerId()), + new ColumnVarChar("origin", 30, UtilWorld.locToStr(token.Origin)), + new ColumnInt("outpostType", token.Type.getId()), + new ColumnInt("ownerClan", token.OwnerClan.getId()), + new ColumnTimestamp("timeSpawned", new Timestamp(token.TimeSpawned)), + new ColumnByte("outpostState", token.OutpostState.getId())); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/SiegeWeaponRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/SiegeWeaponRepository.java new file mode 100644 index 00000000..8f69a596 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/SiegeWeaponRepository.java @@ -0,0 +1,160 @@ +package mineplex.game.clans.clans.siege.repository; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.List; + +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.database.MinecraftRepository; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.siege.SiegeManager; +import mineplex.game.clans.clans.siege.repository.tokens.SiegeWeaponToken; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnTimestamp; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class SiegeWeaponRepository extends RepositoryBase +{ + private static final String CREATE = "CREATE TABLE IF NOT EXISTS clansSiegeWeapons (uniqueId INT NOT NULL," + + "serverId INT NOT NULL," + + "location VARCHAR(30)," + + "ownerClan INT NOT NULL," + + "weaponType TINYINT NOT NULL," + + "health INT NOT NULL," + + "yaw INT NOT NULL," + + "lastFired LONG," + + "entities VARCHAR(200)," + + "PRIMARY KEY (uniqueId));"; + + private static final String GET_WEAPON_BY_ID = "SELECT * FROM clansSiegeWeapons WHERE uniqueId=?;"; + private static final String GET_WEAPONS_BY_CLAN = "SELECT * FROM clansSiegeWeapons WHERE ownerClan=?;"; + private static final String GET_WEAPONS_BY_SERVER = "SELECT * FROM clansSiegeWeapons WHERE serverId=?;"; + + private static final String UPDATE_WEAPON = "UPDATE clansSiegeWeapons SET health=?,yaw=?,lastFired=? WHERE uniqueId=?;"; + private static final String INSERT_WEAPON = "INSERT INTO clansSiegeWeapons VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"; + + private static final String DELETE_WEAPON = "DELETE FROM clansSiegeWeapons WHERE uniqueId=?;"; + + private SiegeManager _siegeManager; + + public SiegeWeaponRepository(JavaPlugin plugin, SiegeManager siegeManager) + { + super(DBPool.getAccount()); + + _siegeManager = siegeManager; + } + + public void deleteWeapon(final int uniqueId) + { + System.out.println("Siege Repo> Deleting weapon " + uniqueId); + + _siegeManager.runAsync(() -> + executeUpdate(DELETE_WEAPON, new ColumnInt("uniqueId", uniqueId)) + ); + } + + public void getWeaponById(final int uniqueId, final Callback callback) + { + _siegeManager.runAsync(() -> + executeQuery(GET_WEAPON_BY_ID, resultSet -> { + SiegeWeaponToken token = new SiegeWeaponToken(); + + resultSet.next(); + + load(token, resultSet); + + callback.run(token); + }, new ColumnInt("uniqueId", uniqueId)) + ); + } + + public void getWeaponsByServer(final int serverId, final Callback> callback) + { + _siegeManager.runAsync(() -> + executeQuery(GET_WEAPONS_BY_SERVER, resultSet -> { + List tokens = Lists.newArrayList(); + + while (resultSet.next()) + { + SiegeWeaponToken token = new SiegeWeaponToken(); + + load(token, resultSet); + + tokens.add(token); + } + + callback.run(tokens); + }, new ColumnInt("serverId", serverId)) + ); + } + + public void getWeaponsByClan(final ClanInfo clan, final Callback> callback) + { + _siegeManager.runAsync(() -> + executeQuery(GET_WEAPONS_BY_CLAN, resultSet -> { + List tokens = Lists.newArrayList(); + + while (resultSet.next()) + { + SiegeWeaponToken token = new SiegeWeaponToken(); + + load(token, resultSet); + + tokens.add(token); + } + + callback.run(tokens); + }, new ColumnInt("ownerClan", clan.getId())) + ); + } + + private void load(SiegeWeaponToken token, ResultSet columns) throws SQLException + { + token.UniqueId = columns.getInt("uniqueId"); + token.Location = UtilWorld.strToLoc(columns.getString("location")); + token.OwnerClan = _siegeManager.getClansManager().getClanUtility().getClanById(columns.getInt("ownerClan")); + token.WeaponType = columns.getByte("weaponType"); + token.Health = columns.getShort("health"); + token.Yaw = columns.getShort("yaw"); + token.LastFired = columns.getTimestamp("lastFired").getTime(); + + System.out.println("Siege Repo> Loaded weapon " + token.UniqueId); + } + + public void updateWeapon(SiegeWeaponToken token) + { +// System.out.println("Siege Repo> Updating weapon " + token.UniqueId); + + _siegeManager.runAsync(() -> + executeUpdate(UPDATE_WEAPON, + new ColumnInt("health", token.Health), + new ColumnInt("yaw", token.Yaw), + new ColumnTimestamp("lastFired", new Timestamp(token.LastFired)), + new ColumnInt("uniqueId", token.UniqueId)) + ); + } + + public void insertWeapon(SiegeWeaponToken token) + { + System.out.println("Siege Repo> Inserting new weapon " + token.UniqueId); + + executeUpdate(INSERT_WEAPON, + new ColumnInt("uniqueId", token.UniqueId), + new ColumnInt("serverId", _siegeManager.getClansManager().getServerId()), + new ColumnVarChar("location", 30, UtilWorld.locToStr(token.Location)), + new ColumnInt("ownerClan", token.OwnerClan.getId()), + new ColumnInt("weaponType", token.WeaponType), + new ColumnInt("health", token.Health), + new ColumnInt("yaw", token.Yaw), + new ColumnTimestamp("lastFired", new Timestamp(token.LastFired)), + new ColumnVarChar("entities", 100, "")); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/tokens/OutpostToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/tokens/OutpostToken.java new file mode 100644 index 00000000..0436fbda --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/tokens/OutpostToken.java @@ -0,0 +1,17 @@ +package mineplex.game.clans.clans.siege.repository.tokens; + +import org.bukkit.Location; + +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.siege.outpost.OutpostState; +import mineplex.game.clans.clans.siege.outpost.OutpostType; + +public class OutpostToken +{ + public int UniqueId; + public Location Origin; + public OutpostType Type; + public ClanInfo OwnerClan; + public long TimeSpawned; + public OutpostState OutpostState; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/tokens/SiegeWeaponToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/tokens/SiegeWeaponToken.java new file mode 100644 index 00000000..274039ed --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/repository/tokens/SiegeWeaponToken.java @@ -0,0 +1,16 @@ +package mineplex.game.clans.clans.siege.repository.tokens; + +import org.bukkit.Location; + +import mineplex.game.clans.clans.ClanInfo; + +public class SiegeWeaponToken +{ + public int UniqueId; + public ClanInfo OwnerClan; + public byte WeaponType; + public Location Location; + public int Health; + public int Yaw; + public long LastFired; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java new file mode 100644 index 00000000..72c21061 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/Cannon.java @@ -0,0 +1,465 @@ +package mineplex.game.clans.clans.siege.weapon; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansGame; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.siege.SiegeManager; +import mineplex.game.clans.clans.siege.repository.tokens.SiegeWeaponToken; +import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile; +import mineplex.game.clans.clans.siege.weapon.util.AccessRule; +import mineplex.game.clans.clans.siege.weapon.util.AccessType; +import mineplex.game.clans.clans.siege.weapon.util.WeaponStateInfo; + +public class Cannon extends SiegeWeapon +{ + public static final ItemStack CANNON_ITEM = new ItemBuilder(Material.SPONGE, 1).setData((byte) 1).setRawTitle(C.Reset + C.cBlue + "Cannon").build(); + + private int _firepower = 1; + + public Cannon(SiegeManager siegeManager, SiegeWeaponToken token) + { + super(300, "Cannon", token, siegeManager.getClansManager(), siegeManager); + + if (_ownerClan == null) + { + System.out.println("[cannon] owner clan null, killing"); + kill(); + return; + } + + System.out.println("Siege> Loading Cannon from token " + token.UniqueId); + + setBoundingBox(1); + + setStateInfo("Unloaded", new WeaponStateInfo(Material.SPONGE, (byte) 1)); + setStateInfo("Loaded", new WeaponStateInfo(Material.SPONGE, (byte) 0)); + + setAmmunitionType(Material.TNT); + + setAmmunitionSlot(4); + setMaximumAmmunitionPerSlot(1); + + _baseDamage = 650; + + setFireRule(new AccessRule(AccessType.LCLICK_BB, player -> + { + if (!isRiding(player)) + { + return false; + } + +// if (!_ownerClan.isMember(player)) +// { +// UtilPlayer.message(player, F.main("Clans", "This cannon is not owned by your Clan.")); +// return false; +// } + + if (_clans.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot fire a cannon whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + if (!canBeFired()) + { + UtilPlayer.message(player, F.main("Clans", "Cannon is not loaded correctly.")); + return false; + } + + if (System.currentTimeMillis() - _lastFired < 20000) + { + UtilPlayer.message(player, F.main("Clans", "Cannon is cooling down (" + F.time(UtilTime.MakeStr(20000 - (System.currentTimeMillis() - _lastFired))) + ")")); + return false; + } + + return true; + })); + + enableInventory(UtilServer.getServer().createInventory(null, InventoryType.DISPENSER, C.cDAquaB + _name), new AccessRule(AccessType.RCLICK_BB, player -> player.equals(getRider()))); + + setRideable(new AccessRule(AccessType.RCLICK_BB, player -> + { + if (!_ownerClan.isMember(player)) + { + UtilPlayer.message(player, F.main("Clans", "This Cannon is not owned by your Clan.")); + return false; + } + + if (getRider() != null && !getRider().equals(player)) + { + UtilPlayer.message(player, F.main("Clans", "Someone is already riding this cannon.")); + return false; + } + + if (_clans.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot ride on a Cannon whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + return !player.equals(getRider()); + })); + } + + public Cannon(Location location, ClanInfo clan, SiegeManager siegeManager, boolean syncWithDb) + { + super(2, location.clone().add(0.5, 0, 0.5), 1400, "Cannon", clan, clan.Clans, siegeManager); + + _syncWithDb = syncWithDb; + + setBoundingBox(1); + + setStateInfo("Unloaded", new WeaponStateInfo(Material.SPONGE, (byte) 1)); + setStateInfo("Loaded", new WeaponStateInfo(Material.SPONGE, (byte) 0)); + + loadEntities(true); + + setFirepowerType(Material.SULPHUR); + setAmmunitionType(Material.TNT); + + setFirepowerSlots(1, 3, 5, 7); + setMaximumFirepowerPerSlot(3); + + setAmmunitionSlot(4); + setMaximumAmmunitionPerSlot(1); + + _baseDamage = 650; + + setFireRule(new AccessRule(AccessType.LCLICK_BB, player -> + { + if (!isRiding(player)) + { + return false; + } + +// if (!_ownerClan.isMember(player)) +// { +// UtilPlayer.message(player, F.main("Clans", "This Cannon is not owned by your Clan.")); +// return false; +// } + + if (_clans.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot fire a Cannon whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + if (!canBeFired()) + { + UtilPlayer.message(player, F.main("Clans", "Cannon is not loaded correctly.")); + return false; + } + + if (System.currentTimeMillis() - _lastFired < 30000) + { + UtilPlayer.message(player, F.main("Clans", "Cannon is cooling down (" + F.time(UtilTime.MakeStr(30000 - (System.currentTimeMillis() - _lastFired))) + ")")); + return false; + } + + return true; + })); + + enableInventory(UtilServer.getServer().createInventory(null, InventoryType.DISPENSER, C.cDAquaB + _name), new AccessRule(AccessType.RCLICK_BB, player -> player.equals(getRider()))); + + setRideable(new AccessRule(AccessType.RCLICK_BB, player -> + { + if (!_ownerClan.isMember(player)) + { + UtilPlayer.message(player, F.main("Clans", "This Cannon is not owned by your Clan.")); + return false; + } + + if (getRider() != null && !getRider().equals(player)) + { + UtilPlayer.message(player, F.main("Clans", "Someone is already riding this Cannon.")); + return false; + } + + if (_clans.hasTimer(player)) + { + UtilPlayer.message(player, F.main("Clans", "You cannot ride on a Cannon whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return false; + } + + return !player.equals(getRider()); + })); + } + + @SuppressWarnings("deprecation") + @EventHandler + protected void InventoryClick(InventoryClickEvent event) + { + if (event.getClickedInventory() == null) + { + return; + } + + if (event.getClick() == ClickType.SHIFT_RIGHT || event.getClick() == ClickType.SHIFT_LEFT) + { + if(_inventory.getViewers().contains(event.getWhoClicked())) + { + event.setCancelled(true); //block shift right clicking tnt into this inventory + getClans().runSyncLater(() -> ((Player) event.getWhoClicked()).updateInventory(), 1L); + } + + return; + } + + if (!event.getClickedInventory().equals(_inventory)) + { + return; + } + + if (event.getSlot() == 0) + { + int oldFirepower = _firepower; + + _firepower = UtilMath.clamp(--_firepower, 1, 3); + + if (oldFirepower != _firepower) + { + ((Player) event.getWhoClicked()).playSound(event.getWhoClicked().getLocation(), Sound.NOTE_PLING, 1.0f, 1.0f); + } + else + { + ((Player) event.getWhoClicked()).playSound(event.getWhoClicked().getLocation(), Sound.NOTE_BASS, 1.0f, 1.0f); + } + + event.setCancelled(true); + } + else if (event.getSlot() == 1) + { + event.setCancelled(true); + } + else if (event.getSlot() == 2) + { + int oldFirepower = _firepower; + + _firepower = UtilMath.clamp(++_firepower, 1, 3); + + if (oldFirepower != _firepower) + { + ((Player) event.getWhoClicked()).playSound(event.getWhoClicked().getLocation(), Sound.NOTE_PLING, 1.0f, 1.0f); + } + else + { + ((Player) event.getWhoClicked()).playSound(event.getWhoClicked().getLocation(), Sound.NOTE_BASS, 1.0f, 1.0f); + } + + event.setCancelled(true); + } + else if (event.getSlot() != _ammunitionSlot) + { + event.setCancelled(true); + } + else if (event.getSlot() == _ammunitionSlot && ClansGame.isDupedFromClassShop(event.getCursor())) + { + event.setCancelled(true); + for (Player p : Bukkit.getOnlinePlayers()) + { + if (ClansManager.getInstance().getClientManager().Get(p).hasPermission(ClansGame.Perm.DUPE_ALERT)) + { + UtilPlayer.message(p, F.elem("[" + C.cRedB + "!" + C.cGray + "] ") + event.getWhoClicked().getName() + " just tried to use a duped item/block!"); + } + } + event.setCursor(new ItemStack(Material.AIR)); + ((Player)event.getWhoClicked()).updateInventory(); + } + } + + private void updateInventory() + { + _inventory.setItem(0, new ItemBuilder(Material.LEVER).setTitle(C.cRed + "-1 Firepower").build()); + _inventory.setItem(1, new ItemBuilder(Material.SULPHUR).setTitle(C.cWhiteB + "Firepower: " + C.cYellow + _firepower).setAmount(_firepower).build()); + _inventory.setItem(2, new ItemBuilder(Material.LEVER).setTitle(C.cGreen + "+1 Firepower").build()); + + for (int slot : UtilCollections.newList(3, 5, 6, 7, 8)) + { + _inventory.setItem(slot, new ItemBuilder(Material.COBBLESTONE).setTitle(C.cGray + "Cannon Wall").build()); + } + } + + protected boolean CustomInventoryValid(int slot, ItemStack item) + { + return true; // all slots are now filled; slot == 0 || slot == 1 || slot == 2; + } + + private void loadEntities(boolean insert) + { + Slime filler = _location.getWorld().spawn(_location.clone(), Slime.class); + + UtilEnt.silence(filler, true); + UtilEnt.vegetate(filler); + + filler.setSize(-1); + filler.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 99999999, 1, true, false)); + + addEntity(filler, "Filler_1"); + + Slime playerMount = _location.getWorld().spawn(_location.clone(), Slime.class); + + UtilEnt.silence(playerMount, true); + UtilEnt.vegetate(playerMount); + + playerMount.setSize(-1); + playerMount.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 99999999, 1, true, false)); + + getEntity("Filler_1").setPassenger(playerMount); + addEntity(playerMount, "PLAYERMOUNT"); + + ArmorStand weapon = _location.getWorld().spawn(_location.clone(), ArmorStand.class); + + UtilEnt.setFakeHead(weapon, true); + weapon.teleport(_location); + weapon.setVisible(false); + weapon.setGravity(false); + + weapon.setPassenger(getEntity("Filler_1")); + + addEntity(weapon, "WEAPON"); + + if (insert) + { + insert(); + } + } + + @Override + public void FindEntities() + { + Lists.newArrayList(_location.getWorld().getEntities()) + .forEach(entity -> + { + if (Integer.toString(_uniqueId).equals(entity.getCustomName())) + { + entity.remove(); + } + }); + + loadEntities(false); + } + + @Override + protected WeaponProjectile CustomFire(double yawRot, double verticalVel, double horizontalVel) + { + Location location = UtilAlg.moveForward(new Location(_location.getWorld(), _location.getX(), _location.getY() + .2, _location.getZ(), (float) yawRot, (float) 0), 0.35, (float) yawRot, false); + + UtilParticle.PlayParticleToAll(ParticleType.LARGE_EXPLODE, location, new Vector(0, 0, 0), .1f, 2, ViewDist.MAX); + UtilServer.getServer().getOnlinePlayers().forEach(player -> player.playSound(location, Sound.EXPLODE, 1.f, 1.f)); + + return new TntProjectile(this, location, yawRot, verticalVel, horizontalVel); + } + + @Override + public String GetNextState() + { + if (getAmmunition() > 0) + { + return "Loaded"; + } + + return "Unloaded"; + } + + protected int getPowerLevel() + { + return _firepower; + } + + @Override + protected void CustomTick() + { + updateInventory(); + + if (getProjectile() != null) + { + UtilParticle.PlayParticleToAll(ParticleType.LARGE_SMOKE, getProjectile().getLocation().add(0, .5, 0), new Vector(0, 0, 0), .1f, 3, ViewDist.MAX); + } + } + + protected void handleLeftClick(Player player) + { + super.handleLeftClick(player); + } + + @Override + protected double[] GetProjectileVelocity() + { + int firepower = getPowerLevel(); + + double hMult = 0; + double yAdd = 0; + + if (firepower == 1) + { + hMult = 1.2; + yAdd = 0.5; + } + else if (firepower == 2) + { + hMult = 1.7; + yAdd = 0.55; + } + else if (firepower >= 3) + { + hMult = 2.35; + yAdd = 0.6; + } + + return new double[] { yAdd, hMult }; + } + + /*@EventHandler + public void explosionEffects(SiegeWeaponExplodeEvent event) + { + List blocks = Stream.generate(() -> UtilAlg.getRandomLocation(event.getProjectile().getLocation(), 4 * getPowerLevel()).getBlock()) + .limit(30) // Generate up to 30 + .distinct() // distinct blocks, + .filter(block -> block.getType() != Material.AIR) // filter for non-air + .filter(block -> // and blocks whose locations aren't blacklisted, + { + ClanTerritory claim = _siegeManager.getClansManager().getClanUtility().getClaim(block.getLocation()); + return claim == null || _siegeManager.getClansManager().getBlacklist().allowed(claim.Owner); + }) + .limit(10) // and take up to 10 of them. + .collect(Collectors.toList()); + + _clans.getExplosion().BlockExplosion( + blocks, + event.getProjectile().getLocation(), + false, + false + ); + }*/ +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/SiegeWeapon.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/SiegeWeapon.java new file mode 100644 index 00000000..b851b3d2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/SiegeWeapon.java @@ -0,0 +1,1027 @@ +package mineplex.game.clans.clans.siege.weapon; + +import java.util.UUID; + +import org.apache.commons.lang.Validate; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.util.EulerAngle; +import org.spigotmc.event.entity.EntityDismountEvent; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautArrayList; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.hologram.Hologram; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClanDeleteEvent; +import mineplex.game.clans.clans.siege.SiegeManager; +import mineplex.game.clans.clans.siege.events.LoadSiegeWeaponEvent; +import mineplex.game.clans.clans.siege.events.MountSiegeWeaponEvent; +import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent; +import mineplex.game.clans.clans.siege.repository.tokens.SiegeWeaponToken; +import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile; +import mineplex.game.clans.clans.siege.weapon.util.AccessRule; +import mineplex.game.clans.clans.siege.weapon.util.AccessType; +import mineplex.game.clans.clans.siege.weapon.util.BarrierCollisionBox; +import mineplex.game.clans.clans.siege.weapon.util.WeaponStateInfo; +import mineplex.game.clans.items.PlayerGear; +import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.DemonicScythe; +import mineplex.game.clans.items.legendaries.GiantsBroadsword; +import mineplex.game.clans.items.legendaries.HyperAxe; +import mineplex.game.clans.items.legendaries.KnightLance; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.game.clans.items.legendaries.MagneticMaul; +import mineplex.game.clans.items.legendaries.WindBlade; + +public abstract class SiegeWeapon implements Listener +{ + // Constants + protected final int _maxHealth; + protected final byte _weaponTypeIdentifier; + + protected SiegeWeaponToken _loadedToken; + + // Managers + protected ClansManager _clans; + protected SiegeManager _siegeManager; + + // Info + protected final int _uniqueId; + + protected final ClanInfo _ownerClan; + protected final Location _location; + protected final String _name; + + protected int _health; + protected String _currentState; + protected boolean _alive = true; + protected boolean _invincible = false; + + // Mechanics + protected final NautArrayList _comprisedOf; + + protected Player _rider; + protected Inventory _inventory; + protected AccessRule _inventoryAccess; + protected BarrierCollisionBox _collisionBox; + + protected AccessRule _fireAccess; + + protected int _boundingBoxSize; + + protected double _yaw; + + protected long _lastRight = -1; + protected long _lastLeft = -1; + protected long _lastFired = -1; + + // Display + protected Hologram _infoHologram; + + // Utility + protected final NautHashMap _registeredStates; + protected final NautHashMap _entityMapping; + + protected boolean _syncWithDb; + + // Customizability + private double[] _forcedVelocity; + + private float[] _lockedYaw; + + protected boolean _isRideable; + protected boolean _invertRotation; + protected AccessRule _mountAccess; + + protected float _rotSpeed = 20.f; + + protected int _ammunitionSlot; + protected Material _ammunitionType; + protected int _maxAmmunition; + + protected NautArrayList _firepowerSlots = new NautArrayList<>(); + protected Material _firepowerType; + protected int _maxFirepowerPerSlot; + + protected int _baseDamage; + + protected WeaponProjectile _projectile; + + public SiegeWeapon(int maxHealth, String name, SiegeWeaponToken token, ClansManager clansManager, SiegeManager siegeManager) + { + _weaponTypeIdentifier = token.WeaponType; + + _loadedToken = token; + + _uniqueId = token.UniqueId; + + _siegeManager = siegeManager; + _location = token.Location; + _name = name; + _health = _maxHealth = maxHealth; + _ownerClan = token.OwnerClan; + + _comprisedOf = new NautArrayList<>(); + _registeredStates = new NautHashMap<>(); + _entityMapping = new NautHashMap<>(); + + _infoHologram = new Hologram(ClansManager.getInstance().getHologramManager(), _location.clone().add(.5, 3, .5), _name + " Health", getDisplayHealth()); + _infoHologram.start(); + + _infoHologram.setInteraction((player, type) -> + { + if (type.equals(ClickType.LEFT)) + { + handleLeftClick(player); + } + else if (type.equals(ClickType.RIGHT)) + { + handleRightClick(player); + } + }); + + UtilServer.RegisterEvents(this); + + _clans = clansManager; + + _yaw = token.Yaw; + _lastFired = token.LastFired; + + _health = token.Health; + + FindEntities(); + } + + public SiegeWeapon(int typeId, Location location, int maxHealth, String name, ClanInfo owner, ClansManager clansManager, SiegeManager siegeManager) + { + _uniqueId = siegeManager.randomId(); + _weaponTypeIdentifier = (byte) typeId; + + _siegeManager = siegeManager; + _location = location; + _name = name; + _health = _maxHealth = maxHealth; + _ownerClan = owner; + + _comprisedOf = new NautArrayList<>(); + _registeredStates = new NautHashMap<>(); + _entityMapping = new NautHashMap<>(); + + _infoHologram = new Hologram(ClansManager.getInstance().getHologramManager(), _location.clone().add(.5, 3, .5), _name + " Health", getDisplayHealth()); + _infoHologram.start(); + + UtilServer.getPluginManager().registerEvents(this, clansManager.getPlugin()); + + _clans = clansManager; + } + + protected void insert() + { + if (_syncWithDb) + _siegeManager.getRepository().insertWeapon(toToken()); + } + + protected int calculateDamage(Player player) + { + ItemStack stack = player.getItemInHand(); + PlayerGear gear = _clans.getGearManager().getPlayerGear(player); + + if (stack == null) + return 1; + + if (gear.getWeapon() != null && gear.getWeapon() instanceof LegendaryItem) + { + if (gear.getWeapon() instanceof AlligatorsTooth) + return 8; + else if (gear.getWeapon() instanceof GiantsBroadsword) + return 10; + else if (gear.getWeapon() instanceof HyperAxe) + return 6; + else if (gear.getWeapon() instanceof MagneticMaul) + return 8; + else if (gear.getWeapon() instanceof WindBlade) + return 7; + else if (gear.getWeapon() instanceof DemonicScythe) + return 8; + else if (gear.getWeapon() instanceof KnightLance) + return 8; + } + + return (int) UtilItem.getAttackDamage(stack.getType()); + } + + protected void enableInventory(Inventory inventory, AccessRule accessRule) + { + _inventory = inventory; + _inventoryAccess = accessRule; + } + + protected void setBoundingBox(int size) + { + Validate.isTrue(size > 0, "Size must be a positive number."); + Validate.isTrue(UtilMath.isOdd(size), "Size must be an odd number."); + + _boundingBoxSize = size; + + _collisionBox = size == 1 ? BarrierCollisionBox.single(_location.clone()) : BarrierCollisionBox.all(_location.clone().subtract((size - 1) / 2, 0, (size - 1) / 2), _location.clone().add(((size - 1) / 2) + .2, size - 1, ((size - 1) / 2) + .2)); + _collisionBox.Construct(); + _collisionBox.registerRight((block, player) -> handleRightClick(player)); + _collisionBox.registerLeft((block, player) -> handleLeftClick(player)); + } + + protected void setBoundingBox(int size, int y) + { + Validate.isTrue(size > 0, "Size must be a positive number."); + Validate.isTrue(UtilMath.isOdd(size), "Size must be an odd number."); + + _boundingBoxSize = size; + + _collisionBox = size == 1 ? BarrierCollisionBox.single(_location.clone()) : BarrierCollisionBox.all(_location.clone().subtract((size - 1) / 2, 0, (size - 1) / 2), _location.clone().add(((size - 1) / 2) + .2, y, ((size - 1) / 2) + .2)); + _collisionBox.Construct(); + _collisionBox.registerRight((block, player) -> handleRightClick(player)); + _collisionBox.registerLeft((block, player) -> handleLeftClick(player)); + } + + private void update() + { + if (getEntity("WEAPON") == null || getEntity("PLAYERMOUNT") == null) + { + kill(); + return; + } + + if (_inventory != null) + checkInventory(); + + _rider = (Player) getEntity("PLAYERMOUNT").getPassenger(); + + if (!GetNextState().equals(_currentState)) + setState(GetNextState()); + + if (_projectile != null && _projectile.hasDied()) + _projectile = null; + + ArmorStand armorStand = (ArmorStand) getEntity("WEAPON"); + double standYaw = _yaw % 360; + + if (getRider() != null) + { + double riderYaw = (getRider().getLocation().getYaw() + (_invertRotation ? 180 : 0)) % 360; + + double dif = riderYaw - standYaw; + if (dif > 180) dif -= 360; + if (dif < -180) dif += 360; + + double yaw = (float) ((float)standYaw + Math.min(dif / _rotSpeed, 4f)); + + if (_lockedYaw != null) + { + float min = _lockedYaw[0]; + float max = _lockedYaw[1]; + + if (yaw < min) + { + yaw = min; + } + + if (yaw > max) + { + yaw = max; + } + } + + armorStand.setHeadPose(new EulerAngle(0, Math.toRadians(CustomRotate(_yaw = yaw)), 0)); + } + } + + protected boolean canBeFired() + { + return getPowerLevel() > 0 && getAmmunition() > 0 && _projectile == null; + } + + public void SetForcedVelocity(double vertical, double horizontal) + { + _forcedVelocity = new double[] { vertical, horizontal }; + } + + public void LockYaw(float minYaw, float maxYaw) + { + _lockedYaw = new float[] { minYaw, maxYaw }; + } + + private void fire(Player player) + { + _lastFired = System.currentTimeMillis(); + + double[] vel = GetProjectileVelocity(); + + if (_forcedVelocity != null) + { + vel = _forcedVelocity; + } + + _inventory.clear(); + + _projectile = CustomFire(((ArmorStand) getEntity("WEAPON")).getHeadPose().getY(), vel[0], vel[1]); + } + + protected void setFireRule(AccessRule rule) + { + _fireAccess = rule; + } + + protected void setFirepowerType(Material type) + { + _firepowerType = type; + } + + protected void setAmmunitionType(Material type) + { + _ammunitionType = type; + } + + protected void setFirepowerSlots(Integer... slots) + { + _firepowerSlots = UtilCollections.newNautList(slots); + } + + protected void setMaximumFirepowerPerSlot(int maxFirepowerPerSlot) + { + _maxFirepowerPerSlot = maxFirepowerPerSlot; + } + + protected void setAmmunitionSlot(int ammunitionSlot) + { + _ammunitionSlot = ammunitionSlot; + } + + protected void setMaximumAmmunitionPerSlot(int maxAmmunition) + { + _maxAmmunition = maxAmmunition; + } + + protected boolean isRiding(Player player) + { + return player.equals(getRider()); + } + + protected void setRideable(AccessRule accessRule) + { + _isRideable = true; + _mountAccess = accessRule; + } + + public void kill() + { + System.out.println("Killing: " + this.getClass().getSimpleName() + " [" + _uniqueId + "]"); + + _siegeManager.runSync(() -> + { + CustomCleanup(); + + _comprisedOf.forEach(Entity::remove); + + _entityMapping.clear(); + _comprisedOf.clear(); + _infoHologram.stop(); + + if (_collisionBox != null) _collisionBox.Destruct(); + + _siegeManager.dead(this); + + _alive = false; + }); + + HandlerList.unregisterAll(this); + } + + private void handleMount(Player player) + { + UtilServer.CallEvent(new MountSiegeWeaponEvent(player, this)); + + if (!CustomMount(player)) + { + getEntity("PLAYERMOUNT").setPassenger(player); + } + + CustomOnMount(player); + } + + private void handleInventoryOpen(Player player) + { + player.openInventory(_inventory); + } + + private void handleRightClick(Player player) + { + if (_lastRight == -1) + { + _lastRight = System.currentTimeMillis(); + } + else + { + if (System.currentTimeMillis() - _lastRight <= 40) + { + return; + } + } + + _lastRight = System.currentTimeMillis(); + + CustomRightClick(player); + + if (_isRideable && _mountAccess.allow(AccessType.RCLICK_BB, player)) + { + handleMount(player); + return; + } + + if (_inventory != null && _inventoryAccess.allow(AccessType.RCLICK_BB, player)) + { + handleInventoryOpen(player); + return; + } + + if (_fireAccess.allow(AccessType.RCLICK_BB, player)) + { + fire(player); + } + } + + protected boolean CustomInventoryValid(int slot, ItemStack item) + { + return false; + } + + private void dismount(Player player) + { + _clans.runSync(() -> player.teleport(player.getLocation().add(0, 1, 0))); + } + + protected void handleLeftClick(Player player) + { + if (player.getGameMode() == GameMode.CREATIVE && player.isSneaking()) + { + removeHealth(getHealth()); + return; + } + + if (_lastLeft == -1) + { + _lastLeft = System.currentTimeMillis(); + } + else + { + if (System.currentTimeMillis() - _lastLeft <= 40) + { + return; + } + } + + _lastLeft = System.currentTimeMillis(); + + CustomLeftClick(player); + + if (_isRideable && _mountAccess.allow(AccessType.LCLICK_BB, player)) + { + handleMount(player); + return; + } + + if (_inventory != null && _inventoryAccess.allow(AccessType.LCLICK_BB, player)) + { + handleInventoryOpen(player); + return; + } + + if (_fireAccess.allow(AccessType.LCLICK_BB, player)) + { + fire(player); + return; + } + + if (!player.equals(_rider) && Recharge.Instance.use(player, "Damage Cannon", 200, false, false)) + { + int health = calculateDamage(player); + + removeHealth(health); + + new Hologram( + _siegeManager.getClansManager().getHologramManager(), + _location.clone().add(UtilMath.random(-1, 1),1.4, UtilMath.random(-1, 1)), + false, + 3500l, + C.cRed + "-" + health) + .start(); + } + } + + + protected abstract double[] GetProjectileVelocity(); + protected abstract String GetNextState(); + protected abstract void FindEntities(); + protected abstract WeaponProjectile CustomFire(double yawRot, double verticalVel, double horizontalVel); + protected void CustomTick() { return; } + protected void CustomOnMount(Player player) { return; } + protected void CustomLeftClick(Player player) { return; } + protected void CustomRightClick(Player player) { return; } + protected void CustomCleanup() { return; } + protected void CustomUpdateState(String state) { return; } + + protected double CustomRotate(double yaw) + { + return yaw; + } + + protected boolean CustomDismount(Player player, Entity entity) { return false; } + protected boolean CustomMount(Player player) { return false; } + + protected final void addEntity(Entity entity, String uniqueName) + { + entity.setCustomName(Integer.toString(_uniqueId)); + entity.setCustomNameVisible(false); + entity.setMetadata("Creature.DoNotDrop", new FixedMetadataValue(_clans.getPlugin(), true)); + UtilEnt.addFlag(entity, "LegendaryAbility.IgnoreMe"); + + _comprisedOf.add(entity); + + _entityMapping.put(uniqueName, entity); + } + + protected final void removeEntity(String uniqueName) + { + Entity entity = _entityMapping.get(uniqueName); + + entity.removeMetadata("Creature.DoNotDrop", _clans.getPlugin()); + UtilEnt.removeFlag(entity, "LegendaryAbility.IgnoreMe"); + + _entityMapping.remove(uniqueName); + _comprisedOf.remove(entity); + + entity.remove(); + } + + protected final Entity getEntity(String uniqueName) + { + return _entityMapping.get(uniqueName); + } + + public final int getHealth() + { + return _health; + } + + public final String getDisplayHealth() + { + return UtilText.getProgress(null, ((double) _health) / ((double) _maxHealth), null, false, 12); + } + + public final void setHealth(int health) + { + _health = UtilMath.clamp(health, 0, _maxHealth); + + _infoHologram.setText(_name + " Health", getDisplayHealth()); + + if (_health == 0 && !_invincible) + kill(); + } + + public final void removeHealth(int health) + { + if (_invincible) return; + setHealth(_health - health); + } + + public final void addHealth(int health) + { + setHealth(_health + health); + } + + public final void setState(String state) + { + Validate.isTrue(_registeredStates.containsKey(state), "Provided state has not yet been registered."); + + ((ArmorStand) getEntity("WEAPON")).setHelmet(new ItemStack(_registeredStates.get(state).getType(), 1, (short) 0, (byte) _registeredStates.get(state).getData())); + + CustomUpdateState(_currentState = state); + } + + public final void setStateInfo(String state, WeaponStateInfo info) + { + _registeredStates.put(state, info); + } + + public final WeaponStateInfo getStateInfo(String state) + { + if (!_registeredStates.containsKey(state)) + _registeredStates.put(state, new WeaponStateInfo(Material.STONE, (byte) 101)); + + return _registeredStates.get(state); + } + + public void checkInventory() + { + for (int slot = 0; slot < _inventory.getSize(); slot++) + { + ItemStack item = _inventory.getItem(slot); + + if (item == null) + continue; + + if (slot == _ammunitionSlot) + { + if (item.getType() != _ammunitionType) + { + if (CustomInventoryValid(slot, item)) + continue; + + if (getRider() != null) + getRider().getInventory().addItem(item); + else + _location.getWorld().dropItem(_location, item); + + _inventory.setItem(slot, null); + } + else + { + if (item.getAmount() > _maxAmmunition) + { + if (getRider() != null) + getRider().getInventory().addItem(new ItemStack(_ammunitionType, item.getAmount() - _maxAmmunition)); + else + _location.getWorld().dropItem(_location, item); + + _inventory.setItem(slot, new ItemStack(_ammunitionType, _maxAmmunition)); + } + else + { + UtilServer.CallEvent(new LoadSiegeWeaponEvent(getRider(), this)); + } + } + } + else if (_firepowerSlots.contains(slot)) + { + if (item.getType() != _firepowerType) + { + if (CustomInventoryValid(slot, item)) + continue; + + if (getRider() != null) + getRider().getInventory().addItem(item); + else + _location.getWorld().dropItem(_location, item); + + _inventory.setItem(slot, null); + } + else + { + if (item.getAmount() > _maxFirepowerPerSlot) + { + if (getRider() != null) + getRider().getInventory().addItem(new ItemStack(_firepowerType, item.getAmount() - _maxFirepowerPerSlot)); + else + _location.getWorld().dropItem(_location, item); + + _inventory.setItem(slot, new ItemStack(_firepowerType, _maxFirepowerPerSlot)); + } + } + } + else + { + if (CustomInventoryValid(slot, item)) + continue; + + if (getRider() != null) + getRider().getInventory().addItem(item); + else + _location.getWorld().dropItem(_location, item); + + _inventory.setItem(slot, null); + } + } + } + + @EventHandler + public void clanDelete(ClanDeleteEvent event) + { + if (event.getClanInfo().getName().equals(_ownerClan.getName())) + { + System.out.println("Killing Siege weapon " + _uniqueId + " because owner clan has been deleted."); + kill(); + } + } + + @EventHandler + public void onSiegeWeaponExplode(SiegeWeaponExplodeEvent event) + { + if (UtilAlg.inBoundingBox(event.getProjectile().getLocation(), _location.clone().subtract(3, 2, 3), _location.clone().add(3, 2, 3))) + { + kill(); + + _ownerClan.inform("One of your Cannons has been destroyed!", null); + UtilTextMiddle.display("Damage", "You destroyed " + F.elem(getOwner().getName()) + "'s " + _name + ".", 10, 60, 10, event.getWeapon().getRider()); + UtilPlayer.message(event.getWeapon().getRider(), F.main("Clans", "You destroyed " + F.elem(getOwner().getName()) + "'s " + _name + ".")); + } + } + + @EventHandler + public void onDamage(EntityDamageEvent event) + { + if (_comprisedOf.contains(event.getEntity())) + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onDmg(EntityDamageByEntityEvent event) + { + if (_comprisedOf.contains(event.getEntity()) && event.getDamager() instanceof Player) + { + if (!((Player) event.getDamager()).equals(_rider)) + { + handleLeftClick((Player) event.getDamager()); + } + + event.setCancelled(true); + } + } + + @EventHandler + public void onCloseInv(InventoryCloseEvent event) + { + if (!event.getInventory().equals(_inventory)) + return; + + ClansManager.getInstance().runSyncLater(() -> { + if (!event.getPlayer().getInventory().equals(_inventory) && canBeFired()) + UtilTextMiddle.display(_name + " Ready", "Power Level: " + C.cGreen + UtilText.repeat("▌", getPowerLevel()) + C.cRed + UtilText.repeat("▌", _maxFirepowerPerSlot - getPowerLevel()), 20, 100, 20, (Player) event.getPlayer()); + }, 3L); + } + + @EventHandler + public void onDismount(EntityDismountEvent event) + { + if (event.getEntity() instanceof Player && (event.getDismounted().equals(getEntity("PLAYERMOUNT")) || CustomDismount((Player) event.getEntity(), event.getDismounted()))) + dismount((Player) event.getEntity()); + } + + @EventHandler + public void onInteract(PlayerInteractAtEntityEvent event) + { + if (_comprisedOf.contains(event.getRightClicked())) + { + handleRightClick(event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.getPlayer().equals(_rider)) + { + return; + } + + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) + { + handleRightClick(event.getPlayer()); + event.setCancelled(true); + } + else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + handleLeftClick(event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void onInteract(PlayerInteractEntityEvent event) + { + if (_comprisedOf.contains(event.getRightClicked())) + { + handleRightClick(event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) + { + if (!event.getBlock().getLocation().getWorld().equals(_location.getWorld())) + { + return; + } + + if (event.getBlock().getLocation().distance(_location) < _boundingBoxSize + 1.65 && event.getBlock().getLocation().getY() <= _location.getY()) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You may not break blocks near a Siege Weapon")); + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) + { + if (!event.getBlock().getLocation().getWorld().equals(_location.getWorld())) + { + return; + } + + if (event.getBlock().getLocation().distance(_location) < _boundingBoxSize + 1.65 && event.getBlock().getLocation().getY() <= _location.getY()) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You may not place blocks near a Siege Weapon")); + event.setCancelled(true); + } + } + + public boolean inProtection(Block block) + { + if (!block.getLocation().getWorld().equals(_location.getWorld())) + { + return false; + } + + return block.getLocation().distance(_location) < _boundingBoxSize + 1.65 && block.getLocation().getY() <= _location.getY() + 2; + } + + @EventHandler + public void onInteract(PlayerArmorStandManipulateEvent event) + { + if (_comprisedOf.contains(event.getRightClicked())) + { + handleRightClick(event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void chunkUnload(ChunkUnloadEvent event) + { + if (_comprisedOf.stream().anyMatch(entity -> entity.getLocation().getChunk().equals(event.getChunk()))) + event.setCancelled(true); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + update(); + + CustomTick(); + } + + public Location getLocation() + { + return _location.clone(); + } + + public double getSize() + { + return _boundingBoxSize; + } + + + public int getBaseDamage() + { + return _baseDamage; + } + + public ClanInfo getOwner() + { + return _ownerClan; + } + + public ClansManager getClans() + { + return _clans; + } + + protected WeaponProjectile getProjectile() + { + return _projectile; + } + + protected int getAmmunition() + { + ItemStack item = _inventory.getItem(_ammunitionSlot); + + if (item != null && item.getType().equals(_ammunitionType)) + return item.getAmount(); + + return 0; + } + + protected int getPowerLevel() + { + int power = 0; + + for (int slot : _firepowerSlots) + { + ItemStack item = _inventory.getItem(slot); + + if (item == null || !item.getType().equals(_firepowerType)) + continue; + + power += _inventory.getItem(slot).getAmount(); + } + + return power / 4; + } + + public int getUniqueId() + { + return _uniqueId; + } + + public Player getRider() + { + return _rider; + } + + public final String getState() + { + return _currentState; + } + + public final boolean shouldSyncWithDb() + { + return _syncWithDb; + } + + public SiegeWeaponToken toToken() + { + SiegeWeaponToken token = new SiegeWeaponToken(); + + token.UniqueId = _uniqueId; + token.OwnerClan = _ownerClan; + token.WeaponType = _weaponTypeIdentifier; + token.Location = _location; + token.Health = _health; + token.Yaw = (int) _yaw; + + return token; + } + + public boolean isPartOf(UUID uniqueId) + { + for (Entity entity : _comprisedOf) + { + if (entity.getUniqueId().equals(uniqueId)) + return true; + } + + return false; + } + + public void setInvincible(boolean invincible) + { + _invincible = invincible; + } + + public boolean isInvincible() + { + return _invincible; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/TntProjectile.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/TntProjectile.java new file mode 100644 index 00000000..bb61ae4c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/TntProjectile.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.clans.siege.weapon; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile; + +public class TntProjectile extends WeaponProjectile +{ + public TntProjectile(SiegeWeapon weapon, Location origin, double yawRot, double yVel, double xMulti) + { + super(weapon, origin, yawRot, yVel, xMulti); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onTntExplode(EntityExplodeEvent event) + { + if (event.getEntity().equals(_projectileEntity)) + { + ((TNTPrimed) event.getEntity()).setFuseTicks(60); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onTntExplode(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + ((TNTPrimed) _projectileEntity).setFuseTicks(60); + } + + @Override + public Entity spawn() + { + TNTPrimed tnt = _origin.getWorld().spawn(_origin, TNTPrimed.class); + + Vector velocity = UtilAlg.getTrajectory( + _origin, + UtilAlg.moveForward( + _origin, + 2., + (float) Math.toDegrees(_yawRot), false)) + .multiply(_xMulti) + .setY(_yVel); + + tnt.setVelocity(velocity); + + return tnt; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/Crater.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/Crater.java new file mode 100644 index 00000000..c8bbf60c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/Crater.java @@ -0,0 +1,119 @@ +package mineplex.game.clans.clans.siege.weapon.projectile; + +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; +import mineplex.game.clans.clans.siege.weapon.projectile.event.CraterExplodeEvent; +import mineplex.game.clans.core.repository.ClanTerritory; + +public class Crater +{ + private final SiegeWeapon _weapon; + private final Location _origin; + private final Player _cause; + + public Crater(SiegeWeapon weapon, WeaponProjectile projectile, Location origin) + { + _weapon = weapon; + _origin = origin; + _cause = projectile.getShooter(); + createExplosion(); + } + + @SuppressWarnings("deprecation") + private void createExplosion() + { + List blocks = Lists.newArrayList(); + List noRepeats = Lists.newArrayList(); + for (Block block : UtilBlock.getInRadius(_origin, 3).keySet()) + { + String locID = block.getLocation().getX() + " " + block.getLocation().getY() + " " + block.getLocation().getZ(); + if (noRepeats.contains(locID)) + { + continue; + } + else + { + noRepeats.add(locID); + } + if (block.getType() == Material.AIR || block.isLiquid() || block.getType() == Material.BEDROCK) + { + continue; + } + ClanTerritory terr = _weapon.getClans().getClanUtility().getClaim(block.getLocation()); + + if (terr != null) + { + if (!ClansManager.getInstance().getBlacklist().allowed(terr.Owner)) + { + continue; + } + ClanInfo clan = ClansManager.getInstance().getClanUtility().getOwner(terr); + if (clan != null && !ClansManager.getInstance().getWarManager().isBeingBesiegedBy(clan, _weapon.getOwner())) + { + continue; + } + } + blocks.add(block); + } + + ClansManager.getInstance().runSyncLater(() -> + { + CraterExplodeEvent event = UtilServer.CallEvent(new CraterExplodeEvent(_weapon, _cause, _origin, blocks)); + UtilParticle.PlayParticleToAll(ParticleType.HUGE_EXPLOSION, _origin, null, 0, 1, ViewDist.NORMAL); + for (Block block : event.getBlocks()) + { + if (block.getType() == Material.CHEST || block.getType() == Material.TRAPPED_CHEST || block.getType() == Material.FURNACE || block.getType() == Material.BURNING_FURNACE || block.getType() == Material.BED_BLOCK) + { + block.breakNaturally(); + } + else if (block.getType() == Material.SMOOTH_BRICK) + { + if (block.getData() != 2) + { + block.setTypeIdAndData(98, (byte)2, true); + } + else + { + block.breakNaturally(); + } + } + else + { + if (Math.random() <= .3) + { + block.breakNaturally(); + } + else + { + block.setType(Material.AIR); + } + } + } + }, 1L); + + Map hitMap = UtilEnt.getInRadius(_origin, 3.5); + for (LivingEntity hit : hitMap.keySet()) + { + ClansManager.getInstance().getDamageManager().NewDamageEvent(hit, _cause, null, DamageCause.ENTITY_EXPLOSION, 7 / hitMap.get(hit), true, true, false, _cause.getName(), "Siege Cannon"); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/CraterBlock.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/CraterBlock.java new file mode 100644 index 00000000..e8ff4058 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/CraterBlock.java @@ -0,0 +1,32 @@ +package mineplex.game.clans.clans.siege.weapon.projectile; + +import org.bukkit.Location; +import org.bukkit.Material; + +public class CraterBlock +{ + public Material Type; + public byte Data; + public double DistanceToOrigin; + + public Location Location; + + public CraterBlock(Location location, double dist, Material type, byte data) + { + Location = location; + DistanceToOrigin = dist; + Type = type; + Data = data; + } + + public CraterBlock(Location location, double dist, Material type) + { + this(location, dist, type, (byte) 0); + } + + public void set() + { + Location.getBlock().setType(Type); + Location.getBlock().setData(Data); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/ProjectileType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/ProjectileType.java new file mode 100644 index 00000000..018255e8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/ProjectileType.java @@ -0,0 +1,7 @@ +package mineplex.game.clans.clans.siege.weapon.projectile; + +public enum ProjectileType +{ + PRIMED_TNT, + FALLING_BLOCK; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/WeaponProjectile.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/WeaponProjectile.java new file mode 100644 index 00000000..2cfa6e33 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/WeaponProjectile.java @@ -0,0 +1,124 @@ +package mineplex.game.clans.clans.siege.weapon.projectile; + +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent; +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; + +public abstract class WeaponProjectile implements Listener +{ + protected Location _origin; + protected Entity _projectileEntity; + + protected SiegeWeapon _weapon; + + protected double _yawRot; + protected double _xMulti; + protected double _yVel; + + protected boolean _dead; + + protected Player _shooter; + + public WeaponProjectile(SiegeWeapon weapon, Location origin, double yawRot, double yVel, double xMulti) + { + _shooter = weapon.getRider(); + _weapon = weapon; + _origin = origin; + _yawRot = yawRot; + _yVel = yVel; + _xMulti = xMulti; + + UtilServer.getPluginManager().registerEvents(this, weapon.getClans().getPlugin()); + + _projectileEntity = spawn(); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_projectileEntity == null || _projectileEntity.isDead()) + { + die(); + return; + } + + if (_projectileEntity.getTicksLived() <= 10) + { + return; + } + + boolean moving = Math.abs(_projectileEntity.getVelocity().getX()) > 0.01 || Math.abs(_projectileEntity.getVelocity().getZ()) > 0.01; + + // Some rough collision detection. Not perfect, but the best I could conjure up myself. + if ((!moving && !UtilBlock.boundless(_projectileEntity.getLocation(), 2)) || (_projectileEntity instanceof TNTPrimed && _projectileEntity.getTicksLived() >= 80)) + { + SiegeWeaponExplodeEvent newEvent = UtilServer.CallEvent(new SiegeWeaponExplodeEvent(_weapon, this)); + + if (!newEvent.isCancelled()) + { + new Crater(_weapon, this, _projectileEntity.getLocation()); + UtilServer.getServer().getOnlinePlayers().forEach(player -> player.playSound(_projectileEntity.getLocation(), Sound.EXPLODE, 1.f, 1.f)); + } + + die(); + return; + } + + if (_projectileEntity.getTicksLived() > (15 * 20)) + { + die(); + } + } + + public boolean hasDied() + { + return _dead; + } + + public Location getLocation() + { + return _projectileEntity.getLocation(); + } + + public void setLocation(Location location) + { + _projectileEntity.teleport(location); + } + + private void die() + { + HandlerList.unregisterAll(this); + + if (_projectileEntity != null) + { + _projectileEntity.remove(); + _projectileEntity = null; + } + + _dead = true; + } + + public abstract Entity spawn(); + + public Player getShooter() + { + return _shooter; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/event/CraterExplodeEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/event/CraterExplodeEvent.java new file mode 100644 index 00000000..b2a97834 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/event/CraterExplodeEvent.java @@ -0,0 +1,78 @@ +package mineplex.game.clans.clans.siege.weapon.projectile.event; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; + +/** + * Event called when a Crater explodes + */ +public class CraterExplodeEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private SiegeWeapon _weapon; + private Player _shooter; + private Location _origin; + private List _blocks; + + public CraterExplodeEvent(SiegeWeapon weapon, Player shooter, Location explosionOrigin, List blocks) + { + _weapon = weapon; + _shooter = shooter; + _origin = explosionOrigin; + _blocks = blocks; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + /** + * Gets the Siege Weapon that shot the projectile which created this crater + * @return The Siege Weapon that shot the projectile which created this crater + */ + public SiegeWeapon getWeapon() + { + return _weapon; + } + + /** + * Gets the player responsible for this crater + * @return The player responsible for this crater + */ + public Player getShooter() + { + return _shooter; + } + + /** + * Gets the location where this explosion originated + * @return The origin point of this explosion + */ + public Location getExplosionOrigin() + { + return _origin; + } + + /** + * Gets a list of all blocks affected by this explosion + * @return A list of all blocks affected by this explosion + */ + public List getBlocks() + { + return _blocks; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/event/PreCraterSetBlockEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/event/PreCraterSetBlockEvent.java new file mode 100644 index 00000000..81bc117f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/projectile/event/PreCraterSetBlockEvent.java @@ -0,0 +1,72 @@ +package mineplex.game.clans.clans.siege.weapon.projectile.event; + +import java.util.Set; + +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.clans.siege.weapon.SiegeWeapon; +import mineplex.game.clans.clans.siege.weapon.projectile.Crater; +import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile; + +public class PreCraterSetBlockEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private SiegeWeapon _weapon; + private WeaponProjectile _projectile; + private Set _blocks; + private Crater _crater; + + + private boolean _cancelled; + + public PreCraterSetBlockEvent(Set blocks, Crater crater, SiegeWeapon weapon, WeaponProjectile projectile) + { + _blocks = blocks; + _crater = crater; + _weapon = weapon; + _projectile = projectile; + } + + public Set getBlocks() + { + return _blocks; + } + + public Crater getCrater() + { + return _crater; + } + + public SiegeWeapon getWeapon() + { + return _weapon; + } + + public WeaponProjectile getProjectile() + { + return _projectile; + } + + public boolean isCancelled() + { + return _cancelled; + } + + public void setCancelled(boolean cancelled) + { + _cancelled = cancelled; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/AccessRule.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/AccessRule.java new file mode 100644 index 00000000..b1eb7b37 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/AccessRule.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.clans.siege.weapon.util; + +import java.util.function.Predicate; + +import org.bukkit.entity.Player; + +public class AccessRule +{ + private Predicate _access; + private AccessType _type; + + public AccessRule(AccessType type, Predicate access) + { + _type = type; + _access = access; + } + + public boolean allow(AccessType type, Player player) + { + return type.equals(_type) && _access.test(player); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/AccessType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/AccessType.java new file mode 100644 index 00000000..6fccb310 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/AccessType.java @@ -0,0 +1,7 @@ +package mineplex.game.clans.clans.siege.weapon.util; + +public enum AccessType +{ + RCLICK_BB, + LCLICK_BB, +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/BarrierCollisionBox.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/BarrierCollisionBox.java new file mode 100644 index 00000000..08b28a04 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/BarrierCollisionBox.java @@ -0,0 +1,251 @@ +package mineplex.game.clans.clans.siege.weapon.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class BarrierCollisionBox implements Listener +{ + private List _collisionBlocks; + + private List> _leftClickListeners; + private List> _rightClickListeners; + + BarrierCollisionBox() + { + _collisionBlocks = new ArrayList<>(); + + _leftClickListeners = new ArrayList<>(); + _rightClickListeners = new ArrayList<>(); + } + + BarrierCollisionBox(List locations) + { + this(); + + _collisionBlocks.addAll(locations); + } + + BarrierCollisionBox(Location start, Location end) + { + this(); + + UtilBlock.getInBoundingBox(start.getBlock().getLocation(), end.getBlock().getLocation(), false).forEach(block -> _collisionBlocks.add(block.getLocation())); + } + + public void Construct() + { + setBlocks(); + + UtilServer.RegisterEvents(this); + } + + public void Destruct() + { + HandlerList.unregisterAll(this); + + resetBlocks(); + + _leftClickListeners.clear(); + _rightClickListeners.clear(); + _collisionBlocks.clear(); + } + + public void Update() + { + setBlocks(); + } + + public void registerLeft(BiConsumer listener) + { + _leftClickListeners.add(listener); + } + + public void registerRight(BiConsumer listener) + { + _rightClickListeners.add(listener); + } + + public void unregisterLeft(BiConsumer listener) + { + _leftClickListeners.remove(listener); + } + + public void unregisterRight(BiConsumer listener) + { + _rightClickListeners.remove(listener); + } + + private void onLeftClick(Location location, Player player) + { + UtilCollections.ForEach(_leftClickListeners, listener -> listener.accept(location, player)); + } + + private void onRightClick(Location location, Player player) + { + UtilCollections.ForEach(_rightClickListeners, listener -> listener.accept(location, player)); + } + + private void resetBlocks() + { + _collisionBlocks + .stream() + .filter(location -> location.getBlock().getType().equals(Material.BARRIER)) + .forEach(location -> location.getBlock().setType(Material.AIR)); + } + + private void setBlocks() + { + for (Location location : _collisionBlocks) + { + location.getBlock().setType(Material.BARRIER); + } + } + + public boolean isInBox(Location location) + { + for (Location other : _collisionBlocks) + { + if (other.equals(location)) + { + return true; + } + } + + return false; + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.FAST) + { + Update(); + } + } + + // Events for interaction with the collision box; + @EventHandler + public void blockDamage(BlockDamageEvent event) + { + if (isInBox(event.getBlock().getLocation())) + { + onLeftClick(event.getBlock().getLocation(), event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void blockBreak(BlockBreakEvent event) + { + if (isInBox(event.getBlock().getLocation())) + { + onLeftClick(event.getBlock().getLocation(), event.getPlayer()); + event.setCancelled(true); + } + } + + @EventHandler + public void interact(PlayerInteractEvent event) + { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) + { + return; + } + + if (isInBox(event.getClickedBlock().getLocation())) + { + onRightClick(event.getClickedBlock().getLocation(), event.getPlayer()); + event.setCancelled(true); + } + } + + public BarrierCollisionBox add(Location... location) + { + _collisionBlocks.addAll(Arrays.asList(location)); + + Update(); + + return this; + } + + public BarrierCollisionBox add(List location) + { + _collisionBlocks.addAll(location); + + Update(); + + return this; + } + + public BarrierCollisionBox remove(Location... location) + { + _collisionBlocks.removeAll(Arrays.asList(location)); + + Update(); + + return this; + } + + public BarrierCollisionBox add(BarrierCollisionBox box, boolean destructOld, boolean cloneListeners) + { + _collisionBlocks.addAll(box._collisionBlocks); + + if (cloneListeners) + { + _leftClickListeners.addAll(box._leftClickListeners); + _rightClickListeners.addAll(box._rightClickListeners); + } + + if (destructOld) + { + box.Destruct(); + } + + Update(); + + return this; + } + + public BarrierCollisionBox add(BarrierCollisionBox box) + { + return add(box, false, false); + } + + public BarrierCollisionBox addAll(Location start, Location end) + { + UtilBlock.getInBoundingBox(start, end).forEach(block -> _collisionBlocks.add(block.getLocation())); + + Update(); + + return this; + } + + public static BarrierCollisionBox all(Location start, Location end) + { + return new BarrierCollisionBox(start, end); + } + + public static BarrierCollisionBox single(Location location) + { + return new BarrierCollisionBox(new ArrayList<>(Arrays.asList(location.getBlock().getLocation()))); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/WeaponStateInfo.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/WeaponStateInfo.java new file mode 100644 index 00000000..b0eae35e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/siege/weapon/util/WeaponStateInfo.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.clans.siege.weapon.util; + +import org.bukkit.Material; + +public class WeaponStateInfo +{ + private Material _material; + private byte _data; + + public WeaponStateInfo(Material material, byte data) + { + _material = material; + _data = data; + } + + public Material getType() + { + return _material; + } + + public byte getData() + { + return _data; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDrop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDrop.java new file mode 100644 index 00000000..d06478d0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDrop.java @@ -0,0 +1,242 @@ +package mineplex.game.clans.clans.supplydrop; + +import java.lang.reflect.Field; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.hologram.Hologram; +import mineplex.core.hologram.HologramManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.supplydrop.SupplyDropManager.SupplyDropType; +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.TileEntity; +import net.minecraft.server.v1_8_R3.TileEntityBeacon; + +public class SupplyDrop +{ + private static Field BEACON_LEVEL; + private static Field BEACON_ENABLED; + + static + { + try + { + BEACON_LEVEL = TileEntityBeacon.class.getDeclaredField("j"); + BEACON_LEVEL.setAccessible(true); + BEACON_ENABLED = TileEntityBeacon.class.getDeclaredField("i"); + BEACON_ENABLED.setAccessible(true); + } + catch (NoSuchFieldException | SecurityException e) + { + e.printStackTrace(); + } + } + + private static final int DROP_TICKS = 20 * 60 * 3; //3 Minutes + private static final int REMOVE_TICKS = DROP_TICKS + (20 * 120); // 2 Minutes + public static final Material SUPPLY_DROP_MATERIAL = Material.BEACON; + public static final String SUPPLY_DROP_FILLED_METADATA = "SUPPLY_DROP_FILLED"; + + private final SupplyDropType _type; + private final mineplex.game.clans.clans.supplydrop.SupplyDropManager.BlockPosition _position; + private final Block _block; + private final Block[] _below = new Block[9]; + @SuppressWarnings("unchecked") + private final Pair[] _oldBelow = new Pair[9]; + private int _ticks; + private boolean _ended; + private final Hologram _hologram; + + @SuppressWarnings("deprecation") + protected SupplyDrop(SupplyDropType type, Block block, HologramManager hologramManager) + { + _type = type; + _position = new mineplex.game.clans.clans.supplydrop.SupplyDropManager.BlockPosition(block); + _block = block; + _ticks = 0; + _ended = false; + _hologram = new Hologram(hologramManager, _block.getLocation().add(0.5, 1.5, 0.5)); + _hologram.setInteraction((player, clickType) -> + { + UtilServer.CallEvent(new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, player.getItemInHand(), _block, _block.getFace(player.getLocation().getBlock()))); + }); + _hologram.start(); + + block.setType(SUPPLY_DROP_MATERIAL); + + int index = 0; + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + Block b = block.getRelative(x, -1, z); + _below[index] = b; + _oldBelow[index] = Pair.create(b.getType(), b.getData()); + b.setType(Material.DIAMOND_BLOCK); + index++; + } + } + } + + private String getChatColor(long millis) + { + if (millis > 30000) + { + return C.cAqua; + } + else if (millis > 10000) + { + return C.cYellow; + } + else + { + return C.cRed; + } + } + + private void placeChest() + { + _block.setType(Material.CHEST); + ClansManager.getInstance().runSyncLater(() -> + { + Chest chest = (Chest) _block.getState(); + + Inventory inventory = chest.getBlockInventory(); + + int i = 0; + for (ItemStack item : _type.generateLootItems()) + { + inventory.setItem(i++, item); + } + chest.update(true); + chest.setMetadata(SUPPLY_DROP_FILLED_METADATA, new FixedMetadataValue(UtilServer.getPlugin(), true)); + }, 5); + } + + public boolean isDropping() + { + return _ticks < DROP_TICKS; + } + + public boolean isActive() + { + return _ticks < REMOVE_TICKS && !_ended; + } + + public Chunk getChunk() + { + return _block.getChunk(); + } + + public mineplex.game.clans.clans.supplydrop.SupplyDropManager.BlockPosition getPosition() + { + return _position; + } + + public int getTicks() + { + return _ticks; + } + + public void tick() + { + if (_ended) + { + return; + } + if (getTicks() < DROP_TICKS) + { + if (getTicks() == 10) + { + try + { + TileEntity tileEntity = ((CraftWorld) _block.getWorld()).getHandle().getTileEntity(new BlockPosition(_block.getX(), _block.getY(), _block.getZ())); + + if (tileEntity instanceof TileEntityBeacon) + { + BEACON_ENABLED.set(tileEntity, true); + BEACON_LEVEL.set(tileEntity, 3); + tileEntity.update(); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + if (getTicks() > 15 && getTicks() % 10 == 0) + { + FireworkEffect effect = FireworkEffect.builder().with(FireworkEffect.Type.BURST).withColor(Color.AQUA, Color.WHITE, Color.GRAY).withFade(Color.BLACK).withFlicker().build(); + UtilFirework.playFirework(_block.getLocation().add(0.5, 0.5, 0.5), effect); + } + + if (getTicks() % 20 == 0) + { + long millis = (DROP_TICKS - getTicks()) * 50; // Multiply by 50 to convert ticks to ms + _hologram.setText(getChatColor(millis) + UtilTime.MakeStr(millis) + " Until Drop"); + } + } + else + { + if (getTicks() == DROP_TICKS) + { + Bukkit.broadcastMessage(F.main("Supply Drop", "A supply drop has landed at " + F.elem(UtilWorld.locToStrClean(_block.getLocation())))); + placeChest(); + } + + // Drop supply drop + if (getTicks() % 20 == 0) + { + long millis = (REMOVE_TICKS - getTicks()) * 50; // Multiply by 50 to convert ticks to ms + _hologram.setText(getChatColor(millis) + UtilTime.MakeStr(millis) + " Remaining"); + } + + if (getTicks() >= REMOVE_TICKS) + { + finish(false); + } + } + + _ticks++; + } + + @SuppressWarnings("deprecation") + public void finish(boolean onDisable) + { + _ended = true; + _hologram.stop(); + for (int i = 0; i < 9; i++) + { + _below[i].setTypeIdAndData(_oldBelow[i].getLeft().getId(), _oldBelow[i].getRight(), false); + } + _block.removeMetadata(SUPPLY_DROP_FILLED_METADATA, UtilServer.getPlugin()); + if (onDisable) + { + _block.setType(Material.AIR); + } + else + { + _block.breakNaturally(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropManager.java new file mode 100644 index 00000000..25a16ba0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropManager.java @@ -0,0 +1,428 @@ +package mineplex.game.clans.clans.supplydrop; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.collect.Lists; + +import mineplex.core.MiniPlugin; +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.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.weight.Weight; +import mineplex.core.common.weight.WeightSet; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.loot.GoldTokenLoot; +import mineplex.game.clans.clans.loot.MountLoot; +import mineplex.game.clans.clans.loot.RuneLoot; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.ItemType; +import mineplex.game.clans.items.RareItemFactory; +import mineplex.game.clans.items.attributes.AttributeContainer; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.game.clans.items.legendaries.MeridianScepter; +import mineplex.game.clans.items.rares.RunedPickaxe; + +public class SupplyDropManager extends MiniPlugin +{ + private SupplyDrop _active = null; + private final Block _dropBlock = Bukkit.getWorld("world").getBlockAt(-31, 55, -7); + private final SupplyDropShop _shop; + + public SupplyDropManager(JavaPlugin plugin) + { + super("Supply Drop", plugin); + + _shop = new SupplyDropShop(this); + } + + @Override + public void disable() + { + if (_active != null) + { + _active.finish(true); + } + } + + public SupplyDropShop getShop() + { + return _shop; + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if (_active != null) + { + if (_active.isActive()) + { + _active.tick(); + } + else + { + _active = null; + } + } + } + + @EventHandler + public void cancelInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + if (!UtilEvent.isAction(event, ActionType.ANY)) + { + return; + } + if (_active == null) + { + return; + } + + if (new BlockPosition(event.getClickedBlock()).equals(_active.getPosition())) + { + event.setCancelled(true); + if (!_active.isActive() || _active.isDropping()) + { + return; + } + if (!event.getClickedBlock().hasMetadata(SupplyDrop.SUPPLY_DROP_FILLED_METADATA)) + { + return; + } + if (UtilPlayer.isSpectator(event.getPlayer()) || event.getPlayer().getGameMode() != GameMode.SURVIVAL) + { + return; + } + _active.finish(false); + _active = null; + } + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) + { + if (_active != null && _active.getChunk().getX() == event.getChunk().getX() && _active.getChunk().getZ() == event.getChunk().getZ()) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + if (_active != null) + { + boolean landed = !_active.isDropping(); + runSyncLater(() -> + { + if (_active != null) + { + if (_active.isDropping()) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "A supply drop is landing at " + F.elem("(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")") + "!")); + } + else if (landed) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "A supply drop has landed at " + F.elem("(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")") + "!")); + } + } + }, 40L); + } + } + + /** + * Checks whether there is a supply drop active on this server + * @return Whether there is a supply drop active on this server + */ + public boolean hasActiveSupplyDrop() + { + return _active != null; + } + + /** + * Checks how many of a certain supply drop type a player owns + * @param player The player to check + * @param type The type of supply drop to check for + * @return The amount of supply drops of that type owned + */ + public int getAmountOwned(Player player, SupplyDropType type) + { + return ClansManager.getInstance().getInventoryManager().Get(player).getItemCount(type.getItemName()); + } + + /** + * Makes a player use a supply drop + * @param user The player to use the supply drop + * @param type The type of supply drop to use + */ + public void useSupplyDrop(Player user, SupplyDropType type) + { + if (getAmountOwned(user, type) < 1) + { + return; + } + if (hasActiveSupplyDrop()) + { + return; + } + _dropBlock.getChunk().load(); + _active = new SupplyDrop(type, _dropBlock, ClansManager.getInstance().getHologramManager()); + ClansManager.getInstance().getInventoryManager().addItemToInventory(user, type.getItemName(), -1); + UtilTextMiddle.display(C.cRed + "Supply Drop", "(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")"); + Bukkit.broadcastMessage(F.main(getName(), "A supply drop has been summoned by " + F.elem(user.getName()) + " at " + F.elem("(" + _active.getPosition()._x + ", " + _active.getPosition()._z + ")") + "!")); + } + + protected static class BlockPosition + { + private final int _x, _y, _z; + + public BlockPosition(Block block) + { + _x = block.getX(); + _y = block.getY(); + _z = block.getZ(); + } + + @Override + public int hashCode() + { + return Objects.hash(_x, _y, _z); + } + + @Override + public boolean equals(Object o) + { + if (o instanceof BlockPosition) + { + BlockPosition pos = (BlockPosition) o; + return pos._x == _x && pos._y == _y && pos._z == _z; + } + + return false; + } + } + + public static enum SupplyDropType + { + NORMAL("Clans Supply Drop", "Supply Drop", 5, 7, () -> + { + GearManager gear = ClansManager.getInstance().getGearManager(); + ItemType[] itemTypes = {ItemType.ARMOR, ItemType.BOW, ItemType.WEAPON}; + Material[] weaponTypes = {Material.IRON_AXE, Material.IRON_SWORD}; + Material[] armorTypes = Stream.of(Material.values()).filter(UtilItem::isArmor).toArray(size -> new Material[size]); + GoldTokenLoot goldLoot = new GoldTokenLoot(30000, 70000); + MountLoot mountLoot = new MountLoot(1, 2); + + return (amount) -> + { + WeightSet> set = new WeightSet<>(); + set.add(1, () -> + { + return RareItemFactory.begin(ItemType.RARE).setRare(RunedPickaxe.class).fabricate(); + }); + set.add(25, () -> + { + ItemType type = UtilMath.randomElement(itemTypes); + Material mat = UtilMath.randomElement((type == ItemType.ARMOR) ? armorTypes : (type == ItemType.BOW ? new Material[] {Material.BOW} : weaponTypes)); + AttributeContainer container = new AttributeContainer(); + + gear.generateAttributes(container, type, ThreadLocalRandom.current().nextInt(1, 3)); + return RareItemFactory.begin(type).setType(mat).setSuperPrefix(container.getSuperPrefix()).setPrefix(container.getPrefix()).setSuffix(container.getSuffix()).fabricate(); + }); + Weight> gold = set.add(4, () -> + { + return goldLoot.getItemStack(); + }); + Weight> mount = set.add(4, () -> + { + return mountLoot.getItemStack(); + }); + + List items = new ArrayList<>(); + for (int i = 0; i < amount; i++) + { + ItemStack item = set.generateRandom().get(); + items.add(set.generateRandom().get()); + if (item.getType() == Material.RABBIT_FOOT) + { + set.remove(gold); + } + if (item.getType() == Material.IRON_BARDING || item.getType() == Material.GOLD_BARDING) + { + set.remove(mount); + } + } + + return items; + }; + }), + GILDED("Clans Gilded Supply Drop", "Gilded Supply Drop", 8, 10, () -> + { + GearManager gear = ClansManager.getInstance().getGearManager(); + List> legendaryTypes = Lists.newArrayList(gear.getFindableLegendaries()); + List> runeableLegendaryTypes = Lists.newArrayList(gear.getFindableLegendaries()); + runeableLegendaryTypes.remove(MeridianScepter.class); + ItemType[] rareTypes = {ItemType.RARE, ItemType.LEGENDARY}; + ItemType[] itemTypes = {ItemType.ARMOR, ItemType.BOW, ItemType.WEAPON}; + Material[] weaponTypes = {Material.IRON_AXE, Material.IRON_SWORD}; + Material[] armorTypes = Stream.of(Material.values()).filter(UtilItem::isArmor).toArray(size -> new Material[size]); + GoldTokenLoot goldLoot = new GoldTokenLoot(30000, 70000); + MountLoot mountLoot = new MountLoot(1, 3); + RuneLoot runeLoot = new RuneLoot(); + + return (amount) -> + { + WeightSet> set = new WeightSet<>(); + set.add(1, () -> + { + ItemType type = UtilMath.randomElement(rareTypes); + RareItemFactory factory = RareItemFactory.begin(type); + if (type == ItemType.RARE) + { + return factory.setRare(RunedPickaxe.class).fabricate(); + } + boolean runed = false; + if (ThreadLocalRandom.current().nextDouble() < 0.02) + { + runed = true; + AttributeContainer container = new AttributeContainer(); + gear.generateAttributes(container, type, ThreadLocalRandom.current().nextInt(1, 4)); + factory.setSuperPrefix(container.getSuperPrefix()).setPrefix(container.getPrefix()).setSuffix(container.getSuffix()); + } + return factory.setLegendary(UtilMath.randomElement(runed ? runeableLegendaryTypes : legendaryTypes)).fabricate(); + }); + set.add(25, () -> + { + ItemType type = UtilMath.randomElement(itemTypes); + Material mat = UtilMath.randomElement((type == ItemType.ARMOR) ? armorTypes : (type == ItemType.BOW ? new Material[] {Material.BOW} : weaponTypes)); + AttributeContainer container = new AttributeContainer(); + + gear.generateAttributes(container, type, ThreadLocalRandom.current().nextInt(1, 4)); + return RareItemFactory.begin(type).setType(mat).setSuperPrefix(container.getSuperPrefix()).setPrefix(container.getPrefix()).setSuffix(container.getSuffix()).fabricate(); + }); + set.add(3, () -> + { + return runeLoot.getItemStack(); + }); + Weight> gold = set.add(4, () -> + { + return goldLoot.getItemStack(); + }); + Weight> mount = set.add(4, () -> + { + return mountLoot.getItemStack(); + }); + + List items = new ArrayList<>(); + int golds = 0; + int mounts = 0; + for (int i = 0; i < amount; i++) + { + ItemStack item = set.generateRandom().get(); + items.add(set.generateRandom().get()); + if (item.getType() == Material.RABBIT_FOOT) + { + if (++golds > 1) + { + set.remove(gold); + } + } + if (item.getType() == Material.IRON_BARDING || item.getType() == Material.GOLD_BARDING) + { + if (++mounts > 2) + { + set.remove(mount); + } + } + } + + return items; + }; + }); + + private final String _item, _display; + private final int _min, _max; + private final Function> _loot; + + private SupplyDropType(String itemName, String displayName, int minItems, int maxItems, Supplier>> loot) + { + _item = itemName; + _display = displayName; + _min = minItems; + _max = maxItems; + _loot = loot.get(); + } + + /** + * Gets the name of this supply drop as recognized by the inventory database + * @return The name of this supply drop as recognized by the inventory database + */ + public String getItemName() + { + return _item; + } + + /** + * Gets the display name for this supply drop + * @return The display name for this supply drop + */ + public String getDisplayName() + { + return _display; + } + + /** + * Gets the minimum items for this type of supply drop + * @return The minimum items for this type of supply drop + */ + public int getMinItems() + { + return _min; + } + + /** + * Gets the maximum items for this type of supply drop + * @return The maximum items for this type of supply drop + */ + public int getMaxItems() + { + return _max; + } + + public List generateLootItems() + { + return _loot.apply(ThreadLocalRandom.current().nextInt(_min, _max + 1)); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropPage.java new file mode 100644 index 00000000..bacd67d6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropPage.java @@ -0,0 +1,73 @@ +package mineplex.game.clans.clans.supplydrop; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.bukkit.entity.Player; + +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.supplydrop.SupplyDropManager.SupplyDropType; + +public class SupplyDropPage extends ShopPageBase +{ + public SupplyDropPage(SupplyDropManager plugin, SupplyDropShop shop, String name, Player player) + { + super(plugin, shop, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), name, player, 27); + + buildPage(); + } + + @Override + protected void buildPage() + { + int[] slots = {12, 14}; + int i = 0; + for (SupplyDropType type : SupplyDropType.values()) + { + int owned = getPlugin().getAmountOwned(getPlayer(), type); + int slot = slots[i++]; + SkinData buttonData = type == SupplyDropType.GILDED ? SkinData.CLANS_GILDED_SUPPLY_DROP : SkinData.CLANS_SUPPLY_DROP; + List buttonLore = new ArrayList<>(); + buttonLore.addAll(Arrays.asList(C.cYellow + "Open a Supply Drop containing powerful items!", + C.cRed + " ", + C.cGreen + ">Click to Activate<", + C.cBlue + " ", + C.cDAqua + "You own " + F.greenElem(String.valueOf(Math.max(owned, 0))) + C.cDAqua + " " + type.getDisplayName() + "s" + )); + if (type == SupplyDropType.GILDED) + { + buttonLore.add(C.cGreen + " "); + buttonLore.add(C.cYellow + "Gilded Supply Drops contain better items!"); + } + addButton(slot, buttonData.getSkull(C.cRed + type.getDisplayName(), buttonLore), (player, clickType) -> + { + if (!Recharge.Instance.use(player, "Clans Box Click", 1000, false, false)) + { + return; + } + if (owned < 1) + { + playDenySound(player); + UtilPlayer.message(player, F.main(getPlugin().getName(), "You do not have enough of that Supply Drop! Purchase some at http://www.mineplex.com/shop!")); + return; + } + if (getPlugin().hasActiveSupplyDrop()) + { + playDenySound(player); + UtilPlayer.message(player, F.main(getPlugin().getName(), "There is already a Supply Drop dropping! Try again later!")); + return; + } + SupplyDropManager manager = getPlugin(); + player.closeInventory(); + manager.useSupplyDrop(player, type); + }); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropShop.java new file mode 100644 index 00000000..0a9d4bf2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/supplydrop/SupplyDropShop.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.clans.supplydrop; + +import org.bukkit.entity.Player; + +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class SupplyDropShop extends ShopBase +{ + public SupplyDropShop(SupplyDropManager plugin) + { + super(plugin, ClansManager.getInstance().getClientManager(), ClansManager.getInstance().getDonationManager(), "Supply Drop"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new SupplyDropPage(getPlugin(), this, "Supply Drops", player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGenerator.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGenerator.java new file mode 100644 index 00000000..7dd23456 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGenerator.java @@ -0,0 +1,47 @@ +package mineplex.game.clans.clans.tntgenerator; + +import java.util.UUID; + +import org.bukkit.block.Block; + +public class TntGenerator +{ + private UUID _creator; + private int _ticks; + private int _stock; + + public TntGenerator(String data) + { + _creator = UUID.fromString(data); + } + + public int getTicks() + { + return _ticks; + } + + public void setTicks(int ticks) + { + _ticks = ticks; + } + + public void incrementTicks() + { + _ticks++; + } + + public int getStock() + { + return _stock; + } + + public void setStock(int stock) + { + _stock = stock; + } + + public UUID getBuyer() + { + return _creator; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGeneratorManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGeneratorManager.java new file mode 100644 index 00000000..0a5d3779 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGeneratorManager.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.clans.tntgenerator; + +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.F; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; + +public class TntGeneratorManager extends MiniPlugin +{ + public static final int SECONDS_PER_TNT = 60 * 60 * 12; // 12 Hours + public static final int MAX_GENERATOR_STOCK = 3; + + private ClansManager _clansManager; + + public TntGeneratorManager(JavaPlugin plugin, ClansManager clansManager) + { + super("Tnt Generator", plugin); + + _clansManager = clansManager; + } + + @EventHandler + public void updateGenerators(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (ClanInfo clanInfo : _clansManager.getClanMap().values()) + { + TntGenerator generator = clanInfo.getGenerator(); + if (generator != null) + { + if (generator.getStock() >= MAX_GENERATOR_STOCK) + { + generator.setTicks(0); + } + else + { + if (generator.getTicks() >= SECONDS_PER_TNT) + { + _clansManager.messageClan(clanInfo, F.main("Clans", "Your " + F.elem("TNT Generator") + " in the " + F.elem("PvP Shop") + " has a new TNT available")); + generator.setStock(generator.getStock() + 1); + generator.setTicks(0); + _clansManager.getClanDataAccess().updateGenerator(clanInfo, null); + } + + generator.incrementTicks(); + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/WarManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/WarManager.java new file mode 100644 index 00000000..86599c07 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/WarManager.java @@ -0,0 +1,375 @@ +package mineplex.game.clans.clans.war; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.game.clans.clans.event.ClanDisbandedEvent; +import mineplex.game.clans.clans.event.ClansPlayerDeathEvent; +import mineplex.game.clans.clans.war.command.WarPointsCommand; +import mineplex.game.clans.clans.war.event.WarSiegeEndEvent; +import mineplex.game.clans.clans.war.event.WarSiegeStartEvent; +import mineplex.game.clans.core.war.ClanWarData; + +public class WarManager extends MiniPlugin implements ScoreboardElement +{ + public enum Perm implements Permission + { + WAR_POINT_COMMAND, + } + + public static final int WAR_START_POINTS = 0; + public static final int WAR_FINISH_POINTS = 25; + public static final long INVADE_LENGTH = 60000L * 30; // 30 Minutes + public static final long WAR_COOLDOWN = 60000L * 30; // 30 Minutes + + private final ClansManager _clansManager; + + /** + * Map of the active war sieges. This is indexed by the clan that is being besieged + */ + private Map> _besiegedMap; + private Map> _besiegerMap; + + public WarManager(JavaPlugin plugin, ClansManager clansManager) + { + super("ClanWar Manager", plugin); + _clansManager = clansManager; + _besiegedMap = new HashMap<>(); + _besiegerMap = new HashMap<>(); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.PLAYER.setPermission(Perm.WAR_POINT_COMMAND, true, true); + } + + public ClansManager getClansManager() + { + return _clansManager; + } + + public List getSiegesOn(ClanInfo besieged) + { + return _besiegedMap.get(besieged.getName()); + } + + public List getSiegesFor(ClanInfo besieger) + { + return _besiegerMap.get(besieger.getName()); + } + + public boolean isBeingBesieged(ClanInfo clanInfo) + { + List sieges = _besiegedMap.get(clanInfo.getName()); + return sieges != null && !sieges.isEmpty(); + } + + public boolean isBesieging(ClanInfo clanInfo) + { + List sieges = _besiegerMap.get(clanInfo.getName()); + return sieges != null && !sieges.isEmpty(); + } + + public boolean isBeingBesiegedBy(ClanInfo besieged, ClanInfo besieger) + { + List sieges = _besiegedMap.get(besieged.getName()); + if (sieges != null && !sieges.isEmpty()) + { + for (WarSiege siege : sieges) + { + if (siege.getBesiegingClan().equals(besieger.getName())) + { + return true; + } + } + } + + return false; + } + + @EventHandler + public void handleDeath(final ClansPlayerDeathEvent event) + { + if (!Clans.HARDCORE) + { + return; + } + ClanInfo deathClan = event.getPlayer().getClan(); + + if (deathClan == null) + { + deathClan = _clansManager.leftRecently(event.getPlayer().getPlayer().getUniqueId(), 60000) == null ? deathClan : _clansManager.leftRecently(event.getPlayer().getPlayer().getUniqueId(), 60000).getLeft(); + } + + if (event.getPlayer() != null && deathClan != null) + { + if (event.getKiller() != null && event.getKiller().getClan() != null) + { + final ClanInfo clan = deathClan; + final ClanInfo killerClan = event.getKiller().getClan(); + + ClanWarData war = clan.getWarData(killerClan); + if (war != null) + { + if (war.isOnCooldown()) + { + // Ignore! + return; + } + + _clansManager.ClanTips.displayTip(TipType.DOMINANCE_RIP, event.getPlayer().getPlayer()); + _clansManager.ClanTips.displayTip(TipType.DOMINANCE_NOOICE, event.getKiller().getPlayer()); + + // War already exists + war.increment(killerClan.getName()); + ClansUtility.ClanRelation rel = _clansManager.getClanUtility().rel(clan, killerClan); + _clansManager.messageClan(killerClan, F.main("Clans", "Your clan gained 1 War Point against " + rel.getColor(false) + + clan.getName() + " " + C.Reset + "(" + killerClan.getFormattedWarPoints(clan) + C.Reset + ")")); + _clansManager.messageClan(clan, F.main("Clans", "Your clan lost 1 War Point against " + rel.getColor(false) + + killerClan.getName() + " " + C.Reset + "(" + clan.getFormattedWarPoints(killerClan) + C.Reset + ")")); + checkWarComplete(war); + + ClanInfo clanA = clan.getName().equals(war.getClanA()) ? clan : killerClan; + ClanInfo clanB = clan.equals(clanA) ? killerClan : clan; + _clansManager.getClanDataAccess().updateWar(clanA, clanB, war, null); + + _clansManager.getScoreboard().refresh(killerClan); + _clansManager.getScoreboard().refresh(clan); + } + else + { + // Need to create war + _clansManager.getClanDataAccess().war(killerClan, clan, WAR_START_POINTS + 1, new Callback() + { + @Override + public void run(ClanWarData data) + { + ClansUtility.ClanRelation rel = _clansManager.getClanUtility().rel(clan, killerClan); + _clansManager.ClanTips.displayTip(TipType.DOMINANCE_RIP, event.getPlayer().getPlayer()); + _clansManager.ClanTips.displayTip(TipType.DOMINANCE_NOOICE, event.getKiller().getPlayer()); + _clansManager.messageClan(killerClan, F.main("Clans", "Your clan gained 1 War Point against " + rel.getColor(false) + clan.getName())); + _clansManager.messageClan(clan, F.main("Clans", "Your clan lost 1 War Point against " + rel.getColor(false) + killerClan.getName())); + + _clansManager.getScoreboard().refresh(killerClan); + _clansManager.getScoreboard().refresh(clan); + } + }); + } + } + } + } + + private void checkWarComplete(ClanWarData war) + { + String besiegerClan = null; + String besiegedClan = null; + + if (war.getClanAPoints() >= WAR_FINISH_POINTS) + { + besiegerClan = war.getClanA(); + besiegedClan = war.getClanB(); + } + else if (war.getClanBPoints() >= WAR_FINISH_POINTS) + { + besiegerClan = war.getClanB(); + besiegedClan = war.getClanA(); + } + + if (besiegedClan != null && besiegerClan != null) + { + // Reset War to 0:0 + war.resetPoints(); + war.setCooldown(WAR_COOLDOWN); + + WarSiege siege = new WarSiege(besiegedClan, besiegerClan); + startSiege(siege); + } + } + + private void startSiege(WarSiege siege) + { + String besieged = siege.getBesiegedClan(); + String besieger = siege.getBesiegingClan(); + + addSiege(besieged, siege, _besiegedMap); + addSiege(besieger, siege, _besiegerMap); + + WarSiegeStartEvent event = new WarSiegeStartEvent(siege); + UtilServer.getServer().getPluginManager().callEvent(event); + } + + private void addSiege(String name, WarSiege siege, Map> siegeMap) + { + if (siegeMap.containsKey(name)) + { + siegeMap.get(name).add(siege); + } + else + { + LinkedList sieges = new LinkedList<>(); + sieges.add(siege); + siegeMap.put(name, sieges); + } + } + + @EventHandler + public void clearSieges(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + long currentTime = System.currentTimeMillis(); + + Iterator>> iterator = _besiegedMap.entrySet().iterator(); + while (iterator.hasNext()) + { + List sieges = iterator.next().getValue(); + Iterator siegeIterator = sieges.iterator(); + while (siegeIterator.hasNext()) + { + WarSiege siege = siegeIterator.next(); + if (currentTime >= siege.getEndTime()) + { + WarSiegeEndEvent endEvent = new WarSiegeEndEvent(siege); + Bukkit.getServer().getPluginManager().callEvent(endEvent); + + List besiegerList = _besiegerMap.get(siege.getBesiegingClan()); + if (besiegerList != null) + { + besiegerList.remove(siege); + if (besiegerList.isEmpty()) + { + _besiegerMap.remove(siege.getBesiegingClan()); + } + } + + siegeIterator.remove(); + } + } + + if (sieges.isEmpty()) + iterator.remove(); + } + } + + @EventHandler + public void onSiegeStart(WarSiegeStartEvent event) + { + Bukkit.broadcastMessage(F.main("War", F.elem(event.getWarSiege().getBesiegingClan()) + " can now besiege " + F.elem(event.getWarSiege().getBesiegedClan()))); + } + + @EventHandler + public void onSiegeEnd(WarSiegeEndEvent event) + { + Bukkit.broadcastMessage(F.main("War", F.elem(event.getWarSiege().getBesiegingClan()) + "'s siege against " + F.elem(event.getWarSiege().getBesiegedClan()) + " has ended.")); + + } + + @Override + public void addCommands() + { + addCommand(new WarPointsCommand(this)); + } + + @EventHandler + public void cancelDisband(ClanDisbandedEvent event) + { + ClanInfo clan = event.getClan(); + if (isBeingBesieged(clan) || isBesieging(clan)) + { + UtilPlayer.message(event.getDisbander(), F.main("Clans", "Clans cannot be disbanded in the middle of a siege")); + event.setCancelled(true); + } + } + + @EventHandler + public void onPlaceTNT(BlockPlaceEvent event) + { + if (event.getBlockPlaced().getType() == Material.TNT) + { + event.setCancelled(true); + event.setBuild(false); + UtilPlayer.message(event.getPlayer(), F.main("Clans", "TNT cannot be used outside of a siege cannon!")); + } + } + + @EventHandler + public void onTNTDispense(BlockDispenseEvent event) + { + if (event.getItem().getType() == Material.TNT) + { + event.setCancelled(true); + } + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + List element = new ArrayList(); + + ClanInfo clan = _clansManager.getClan(player); + + if (clan != null) + { + List besiegedList = _besiegedMap.get(clan.getName()); + List besiegerList = _besiegerMap.get(clan.getName()); + + if (besiegerList != null && !besiegerList.isEmpty()) + { + for (WarSiege siege : besiegerList) + { + element.add(" "); + element.add(C.cPurpleB + "Besieging"); + element.add(" " + siege.getBesiegedClan()); + element.add(" " + UtilTime.convertString(Math.max(siege.getTimeLeft(), 0), 1, UtilTime.TimeUnit.FIT)); + } + } + + if (besiegedList != null && !besiegedList.isEmpty()) + { + for (WarSiege siege : besiegedList) + { + element.add(" "); + element.add(C.cRedB + "Besieged"); + element.add(" " + siege.getBesiegingClan()); + element.add(" " + UtilTime.convertString(Math.max(siege.getTimeLeft(), 0), 1, UtilTime.TimeUnit.FIT)); + } + } + } + + return element; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/WarSiege.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/WarSiege.java new file mode 100644 index 00000000..12f124c7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/WarSiege.java @@ -0,0 +1,42 @@ +package mineplex.game.clans.clans.war; + +public class WarSiege +{ + private String _besiegedClan; + private String _besiegingClan; + private long _startTime; + private long _endTime; + + public WarSiege(String besiegedClan, String besiegingClan) + { + _besiegedClan = besiegedClan; + _besiegingClan = besiegingClan; + _startTime = System.currentTimeMillis(); + _endTime = _startTime + WarManager.INVADE_LENGTH; + } + + public long getTimeLeft() + { + return _endTime - System.currentTimeMillis(); + } + + public String getBesiegedClan() + { + return _besiegedClan; + } + + public String getBesiegingClan() + { + return _besiegingClan; + } + + public long getStartTime() + { + return _startTime; + } + + public long getEndTime() + { + return _endTime; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/command/WarPointsCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/command/WarPointsCommand.java new file mode 100644 index 00000000..f9d6bbdc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/command/WarPointsCommand.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.clans.war.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.war.WarManager; +import mineplex.game.clans.core.war.ClanWarData; + +public class WarPointsCommand extends CommandBase +{ + public WarPointsCommand(WarManager plugin) + { + super(plugin, WarManager.Perm.WAR_POINT_COMMAND, "warpoints", "wp", "dom"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (!Clans.HARDCORE) + { + UtilPlayer.message(caller, F.main("Clans", "This is not a hardcore server!")); + return; + } + ClansManager clansManager = Plugin.getClansManager(); + ClanInfo clan = clansManager.getClan(caller); + + if (clan == null) + { + UtilPlayer.message(caller, F.main("War", "You are not in a clan")); + return; + } + + if (args.length == 1) + { + ClanInfo search = clansManager.getClanUtility().searchClanPlayer(caller, args[0], true); + if (search == null) return; + + String searchName = clansManager.getClanUtility().name(search, clan); + String selfName = clansManager.getClanUtility().name(clan, clan); + + ClanWarData war = clan.getWarData(search); + if (war == null) + { + UtilPlayer.message(caller, F.main("War", "War Status with " + searchName)); + UtilPlayer.message(caller, F.main("War", "War Points: " + F.elem("" + WarManager.WAR_START_POINTS))); + } + else + { + UtilPlayer.message(caller, F.main("War", "War Status with " + searchName)); + UtilPlayer.message(caller, F.main("War", "Initiated by: " + (war.getClanA().equals(clan.getName()) ? selfName : searchName))); + UtilPlayer.message(caller, F.main("War", "War Points: " + clan.getFormattedWarPoints(search))); + UtilPlayer.message(caller, F.main("War", "Age: " + F.elem(UtilTime.convertString(System.currentTimeMillis() - war.getTimeFormed().getTime(), 1, UtilTime.TimeUnit.FIT)))); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarEndEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarEndEvent.java new file mode 100644 index 00000000..d9fbc4cb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarEndEvent.java @@ -0,0 +1,26 @@ +package mineplex.game.clans.clans.war.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.core.war.ClanWarData; + +public class WarEndEvent extends Event +{ + private ClanWarData _war; + + public WarEndEvent(ClanWarData war) + { + _war = war; + } + + public ClanWarData getWar() + { + return _war; + } + + // Bukkit event stuff + private static final HandlerList handlers = new HandlerList(); + public static HandlerList getHandlerList() { return handlers; } + public HandlerList getHandlers() { return handlers; } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarSiegeEndEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarSiegeEndEvent.java new file mode 100644 index 00000000..dcd300af --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarSiegeEndEvent.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.clans.war.event; + +import mineplex.game.clans.clans.war.WarSiege; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called when a war siege is ended + */ +public class WarSiegeEndEvent extends Event +{ + private WarSiege _warSiege; + + public WarSiegeEndEvent(WarSiege warSiege) + { + _warSiege = warSiege; + } + + public WarSiege getWarSiege() + { + return _warSiege; + } + + // Bukkit event stuff + private static final HandlerList handlers = new HandlerList(); + public static HandlerList getHandlerList() { return handlers; } + public HandlerList getHandlers() { return handlers; } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarSiegeStartEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarSiegeStartEvent.java new file mode 100644 index 00000000..30e7d2d7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarSiegeStartEvent.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.clans.war.event; + +import mineplex.game.clans.clans.war.WarSiege; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called when a war siege is started + */ +public class WarSiegeStartEvent extends Event +{ + private WarSiege _warSiege; + + public WarSiegeStartEvent(WarSiege warSiege) + { + _warSiege = warSiege; + } + + public WarSiege getWarSiege() + { + return _warSiege; + } + + // Bukkit event stuff + private static final HandlerList handlers = new HandlerList(); + public static HandlerList getHandlerList() { return handlers; } + public HandlerList getHandlers() { return handlers; } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarStartEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarStartEvent.java new file mode 100644 index 00000000..131021ac --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/war/event/WarStartEvent.java @@ -0,0 +1,26 @@ +package mineplex.game.clans.clans.war.event; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.game.clans.core.war.ClanWarData; + +public class WarStartEvent extends Event +{ + private ClanWarData _war; + + public WarStartEvent(ClanWarData war) + { + _war = war; + } + + public ClanWarData getWar() + { + return _war; + } + + // Bukkit event stuff + private static final HandlerList handlers = new HandlerList(); + public static HandlerList getHandlerList() { return handlers; } + public HandlerList getHandlers() { return handlers; } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/warpoints/WarPointEvasion.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/warpoints/WarPointEvasion.java new file mode 100644 index 00000000..40965825 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/warpoints/WarPointEvasion.java @@ -0,0 +1,118 @@ +package mineplex.game.clans.clans.warpoints; + +import com.google.common.collect.Maps; +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.*; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.UUID; + +public class WarPointEvasion extends MiniPlugin +{ + private HashMap _chunkCooldown; + private HashMap _playerCooldown; + + private final long COOLDOWN_TIME = 1000 * 60 * 10; + + public WarPointEvasion(JavaPlugin plugin) + { + super("WP Evasion", plugin); + + _chunkCooldown = Maps.newHashMap(); + _playerCooldown = Maps.newHashMap(); + } + + @EventHandler + public void updateCooldown(UpdateEvent event) + { + if(!event.getType().equals(UpdateType.SEC)) return; + + for (Iterator chunkIterator = _chunkCooldown.keySet().iterator(); chunkIterator.hasNext();) + { + Chunk chunk = chunkIterator.next(); + + if (UtilTime.elapsed(_chunkCooldown.get(chunk), COOLDOWN_TIME)) + chunkIterator.remove(); + } + + + for (Iterator uuidIterator = _playerCooldown.keySet().iterator(); uuidIterator.hasNext();) + { + UUID uuid = uuidIterator.next(); + + if (UtilTime.elapsed(_playerCooldown.get(uuid), COOLDOWN_TIME)) + { + uuidIterator.remove(); + + Player player = Bukkit.getPlayer(uuid); + if (player != null && player.isOnline()) + { + if(ClansManager.getInstance().getClan(player) == null) + { + player.sendMessage(F.main("Clans", "You can now create a clan.")); + } + } + } + } + } + + @EventHandler + public void onClaim(PlayerPreClaimTerritoryEvent event) + { + Chunk chunk = event.getClaimedChunk(); + + if (_chunkCooldown.containsKey(chunk)) + { + event.setCancelled(true); + event.getClaimer().sendMessage(F.main("Clans", "You cannot claim this chunk for another " + UtilTime.convertString(COOLDOWN_TIME - (System.currentTimeMillis() - _chunkCooldown.get(chunk)), 1, UtilTime.TimeUnit.MINUTES))); + } + } + + @EventHandler + public void onunClaim(PlayerUnClaimTerritoryEvent event) + { + _chunkCooldown.put(event.getUnClaimedChunk(), System.currentTimeMillis()); + } + + @EventHandler + public void onClanDisband(ClanDisbandedEvent event) + { + _playerCooldown.put(event.getDisbander().getUniqueId(), System.currentTimeMillis()); + } + + @EventHandler + public void onClanLeave(ClanLeaveEvent event) + { + _playerCooldown.put(event.getPlayer().getUuid(), System.currentTimeMillis()); + } + + + @EventHandler + public void onClanCreate(ClanCreatedEvent event) + { + if (event.getFounder() == null) + return; + + if (_playerCooldown.containsKey(event.getFounder().getUniqueId())) + { + event.setCancelled(true); + event.getFounder().sendMessage(F.main("Clans", "You cannot create a clan for another " + UtilTime.convertString(COOLDOWN_TIME - (System.currentTimeMillis() - _playerCooldown.get(event.getFounder().getUniqueId())), 1, UtilTime.TimeUnit.MINUTES))); + } + } + + public void resetCooldown(UUID uuid) + { + _playerCooldown.remove(uuid); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/EventTerrainFinder.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/EventTerrainFinder.java new file mode 100644 index 00000000..d8b89874 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/EventTerrainFinder.java @@ -0,0 +1,185 @@ +package mineplex.game.clans.clans.worldevent; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.ClansManager; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +import com.google.common.collect.Lists; + +public class EventTerrainFinder +{ + private static final long EVENT_AREA_COOLDOWN = UtilTime.convert(2, TimeUnit.HOURS, TimeUnit.MILLISECONDS); + private ClansManager _clansManager; + + public EventTerrainFinder(ClansManager clansManager) + { + _clansManager = clansManager; + } + + public Location findAreaInBorderlands(boolean force) + { + List locs = Lists.newArrayList(); + locs.addAll(Arrays.asList(EventLocation.values())); + locs.sort(new Comparator() + { + public int compare(EventLocation loc1, EventLocation loc2) + { + if (!UtilTime.elapsed(loc1.getLastUsed(), EVENT_AREA_COOLDOWN)) + { + return 1; + } + if (!UtilTime.elapsed(loc2.getLastUsed(), EVENT_AREA_COOLDOWN)) + { + return -1; + } + int[] rand = new int[] {1, -1}; + return rand[new Random().nextInt(rand.length)]; + } + }); + + for (EventLocation loc : locs) + { + if (!UtilTime.elapsed(loc.getLastUsed(), EVENT_AREA_COOLDOWN)) + { + continue; + } + if (_clansManager.getClanUtility().getClaim(loc.getLocation()) == null || _clansManager.getClanUtility().getClaim(loc.getLocation()).Owner.contains("Borderlands")) + { + loc.use(); + return loc.getLocation(); + } + } + + if (force && !locs.isEmpty()) + { + EventLocation loc = locs.get(UtilMath.r(locs.size())); + loc.use(); + return loc.getLocation(); + } + + return null; + } + + public Location locateSpace(Location areaSource, int areaRadius, int xArea, int yArea, int zArea, boolean replaceBlocks, boolean aboveOther, Set otherBlock) + { + for (int i = 0; i < 20; i++) + { + int x = UtilMath.r(areaRadius * 2) - areaRadius + areaSource.getBlockX(); + int z = UtilMath.r(areaRadius * 2) - areaRadius + areaSource.getBlockZ(); + + Block block = UtilBlock.getHighest(areaSource.getWorld(), x, z); + + if (!aboveOther) if (otherBlock.contains(block.getRelative(BlockFace.DOWN))) continue; + + boolean valid = true; + + int overlaps = 0; + + // Previous + for (x = -xArea; x <= xArea; x++) + { + for (z = -zArea; z <= zArea; z++) + { + for (int y = 0; y <= yArea; y++) + { + // Check Blocks + Block cur = areaSource.getWorld().getBlockAt(block.getX() + x, block.getY() + y, block.getZ() + z); + + if (cur.getRelative(BlockFace.DOWN).isLiquid()) + { + valid = false; + break; + } + + if (otherBlock.contains(cur)) + { + valid = false; + break; + } + + // Check Area + if (!UtilBlock.airFoliage(cur)) overlaps += 1; + } + + if (!valid) break; + } + + if (!valid) break; + } + + if (!replaceBlocks && overlaps > 0) continue; + + if (!valid) continue; + + return block.getLocation(); + } + + return null; + } + + /** + * Enum with locations around the map for world events to spawn + */ + private static enum EventLocation + { + ONE("world", -662, 64, -1108), + TWO("world", 738, 64, -986), + THREE("world", 1180, 64, -435), + FOUR("world", 995, 64, 550), + FIVE("world", 375, 64, 1142), + SIX("world", -479, 64, 975), + SEVEN("world", -1140, 64, 449), + EIGHT("world", -1014, 64, -342); + + private String _world; + private double _x, _y, _z; + private long _last = 0; + + private EventLocation(String worldName, double x, double y, double z) + { + _world = worldName; + _x = x; + _y = y; + _z = z; + } + + /** + * Returns the Bukkit center location for this event space + * @return The Bukkit center location for this event space + */ + public Location getLocation() + { + return new Location(UtilWorld.getWorld(_world), _x, _y, _z); + } + + /** + * Gets the last time this event space has been used + * @return The last time this event space has been used + */ + public Long getLastUsed() + { + return _last; + } + + /** + * Updates this event space's last used time to now + */ + public void use() + { + _last = System.currentTimeMillis(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java new file mode 100644 index 00000000..e171b03d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java @@ -0,0 +1,337 @@ +package mineplex.game.clans.clans.worldevent; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.collect.Lists; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.blood.Blood; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.bosstoken.BossTokenShop; +import mineplex.game.clans.clans.loot.LootManager; +import mineplex.game.clans.clans.regions.ClansRegions; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.game.clans.clans.worldevent.boss.BossArenaLocationFinder; +import mineplex.game.clans.clans.worldevent.command.WorldEventCommand; +import mineplex.game.clans.clans.worldevent.raid.RaidManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +public class WorldEventManager extends MiniPlugin implements ScoreboardElement +{ + public enum Perm implements Permission + { + WORLD_EVENT_COMMAND, + START_EVENT_COMMAND, + STOP_EVENT_COMMAND, + } + + private final List _runningEvents; + + private Random _random; + private ClansManager _clansManager; + private EventTerrainFinder _terrainFinder; + private BossArenaLocationFinder _bossFinder; + private DamageManager _damageManager; + private LootManager _lootManager; + private BlockRestore _blockRestore; + + private long _nextEventStart; + + private RaidManager _raidManager; + + private BossTokenShop _shop; + + public WorldEventManager(JavaPlugin plugin, ClansManager clansManager, DamageManager damageManager, LootManager lootManager, BlockRestore blockRestore, ClansRegions clansRegions) + { + super("World Event", plugin); + + _random = new Random(); + _terrainFinder = new EventTerrainFinder(clansManager); + _bossFinder = new BossArenaLocationFinder(UtilWorld.getWorld("world")); + _clansManager = clansManager; + _damageManager = damageManager; + _lootManager = lootManager; + _blockRestore = blockRestore; + _runningEvents = new LinkedList<>(); + + _shop = new BossTokenShop(this); + + new Blood(plugin); + + _raidManager = new RaidManager(plugin); + + updateNextEventTime(); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.WORLD_EVENT_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.START_EVENT_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.STOP_EVENT_COMMAND, true, true); + } + + public void addCommands() + { + addCommand(new WorldEventCommand(this)); + } + + @Override + public void disable() + { + for (WorldEvent event : _runningEvents) + { + event.stop(true); + } + _runningEvents.clear(); + _raidManager.onDisable(); + } + + public boolean isInEvent(Location location, boolean icePrisonCheck) + { + for (WorldEvent event : _runningEvents) + { + if (event.isInBounds(location, true)) + { + if (!icePrisonCheck || !event.allowsIcePrison()) + { + return true; + } + } + } + + return false; + } + + public BossTokenShop getShop() + { + return _shop; + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + boolean removed = _runningEvents.removeIf(e -> e.getState() == EventState.STOPPED); + + if (removed && _runningEvents.size() == 0) + { + updateNextEventTime(); + } + + if (_runningEvents.size() == 0 && System.currentTimeMillis() >= _nextEventStart) + { + if (UtilServer.getPlayers().length > 0) + { + tryStartEvent(); + } + else + { + updateNextEventTime(); + } + } + } + + public WorldEventType randomEvent() + { + if (_runningEvents.size() == 0) + { + if (UtilServer.getPlayers().length > 0) + { + return tryStartEvent(); + } + } + return null; + } + + private WorldEventType tryStartEvent() + { + WorldEventType[] types = WorldEventType.values(); + if (types.length == 0) + { + return null; + } + else + { + WorldEventType type = types[_random.nextInt(types.length)]; + //Location location = _terrainFinder.findAreaInBorderlands(false); + //if (location != null) + { + initializeEvent(type.createInstance(this)); + return type; + } + //else + //{ + // Try again in 5 minutes + //_nextEventStart = System.currentTimeMillis() + (5 * 60 * 1000); + //} + } + } + + private void initializeEvent(WorldEvent event) + { + if (event == null) + { + throw new RuntimeException("WorldEvent may not be null"); + } + + event.start(); + _runningEvents.add(event); + } + + public WorldEvent startEventFromName(String name) + { + WorldEventType eventType = WorldEventType.valueOf(name); + if (eventType != null) + { + WorldEvent event = eventType.createInstance(this); + if (event == null) + { + return null; + } + initializeEvent(event); + return event; + } + + return null; + } + + public WorldEvent startEventFromType(WorldEventType eventType) + { + if (eventType != null) + { + //Location location = _terrainFinder.findAreaInBorderlands(true); + WorldEvent event = eventType.createInstance(this); + if (event != null) + { + initializeEvent(event); + } + return event; + } + + return null; + } + + public void clearEvents() + { + Iterator iterator = _runningEvents.iterator(); + while (iterator.hasNext()) + { + WorldEvent event = iterator.next(); + event.stop(true); + iterator.remove(); + } + + updateNextEventTime(); + } + + public ClansManager getClans() + { + return _clansManager; + } + + public DamageManager getDamage() + { + return _damageManager; + } + + public LootManager getLoot() + { + return _lootManager; + } + + public EventTerrainFinder getTerrainFinder() + { + return _terrainFinder; + } + + public BossArenaLocationFinder getBossArenaLocationFinder() + { + return _bossFinder; + } + + public RaidManager getRaidManager() + { + return _raidManager; + } + + private void updateNextEventTime() + { + // 45 Minutes + (0 - 15 Minutes) + long waitTime = (45 * 60 * 1000) + _random.nextInt(15 * 60 * 1000); + _nextEventStart = System.currentTimeMillis() + waitTime; + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + List output = Lists.newArrayList(); + + Iterator iterator = _runningEvents.iterator(); + while (iterator.hasNext()) + { + WorldEvent event = iterator.next(); + + if (event.getState() == EventState.LIVE) + { + output.add(" "); + output.add(C.cAqua + C.Bold + "Event"); + + Location eventLocation = event.getCenterLocation(); + String locationString = eventLocation.getBlockX() + ", " + eventLocation.getBlockY() + ", " + eventLocation.getBlockZ(); + output.add(" " + C.cWhite + event.getName()); + output.add(" " + C.cWhite + locationString); + + List scoreboardLines = event.getLines(manager, player, out); + if (scoreboardLines != null) + { + output.addAll(scoreboardLines); + } + + break; + } + } + + return output; + } + + public BlockRestore getBlockRestore() + { + return _blockRestore; + } + + public List getEvents() + { + return _runningEvents; + } + + public DisguiseManager getDisguiseManager() + { + return getClans().getDisguiseManager(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java new file mode 100644 index 00000000..a6b972c7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.clans.worldevent; + +import java.util.function.Function; + +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemBoss; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss; +import mineplex.game.clans.clans.worldevent.capturepoint.CapturePointEvent; +import mineplex.game.clans.clans.worldevent.undead.UndeadCity; + +public enum WorldEventType +{ + //SLIME_KING("Slime King", SlimeBoss.class, 30), + //KING_OF_THE_HILL("King of The Hill", KingHill.class, 30), + //UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30), + //IRON_WIZARD("Iron Wizard", GolemBoss.class, 30), + //BROOD_MOTHER("Brood Mother", SpiderBoss.class, 30), + //SKELETON_KING("Skeleton King", SkeletonBoss.class, 30) + IRON_WIZARD("Iron Wizard", GolemBoss::new), + SKELETON_KING("Skeleton King", SkeletonBoss::new), + CAPTURE_POINT("Capture Point", CapturePointEvent::new), + UNDEAD_CITY("Undead City", UndeadCity::new) + ; + + private String _name; + private Function _creator; + + private WorldEventType(String name, Function creator) + { + _name = name; + _creator = creator; + } + + public WorldEvent createInstance(WorldEventManager eventManager) + { + WorldEvent worldEvent = null; + + if (_creator != null) + { + worldEvent = _creator.apply(eventManager); + } + + return worldEvent; + } + + public String getName() + { + return _name; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/BossAbility.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/BossAbility.java new file mode 100644 index 00000000..8ed1186c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/BossAbility.java @@ -0,0 +1,109 @@ +package mineplex.game.clans.clans.worldevent.api; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; + +public abstract class BossAbility, Y extends LivingEntity> implements Listener +{ + private T _creature; + private Map _damaged = new HashMap<>(); + + public BossAbility(T creature) + { + _creature = creature; + } + + public abstract boolean canMove(); + + public abstract boolean inProgress(); + + public abstract boolean hasFinished(); + + public abstract void setFinished(); + + public abstract void tick(); + + public boolean canDamage(Entity player) + { + if (_damaged.containsKey(player.getUniqueId())) + { + + if (!UtilTime.elapsed(_damaged.get(player.getUniqueId()), 400)) + { + return false; + } + } + + _damaged.put(player.getUniqueId(), System.currentTimeMillis()); + return true; + } + + public int getCooldown() + { + return 3; + } + + public Y getEntity() + { + return getBoss().getEntity(); + } + + public T getBoss() + { + return _creature; + } + + public Location getLocation() + { + return getEntity().getLocation(); + } + + public Player getTarget() + { + return getTarget(30); + } + + public Player getTarget(double minDistance, double maxDistance) + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getLocation(), maxDistance, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getLocation()); + + if (d < minDistance) + { + continue; + } + + if (target == null || dist > d) + { + target = player; + dist = d; + } + } + + return target; + } + + public Player getTarget(double maxDistance) + { + return getTarget(0, maxDistance); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/BossPassive.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/BossPassive.java new file mode 100644 index 00000000..c2387ea0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/BossPassive.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.clans.worldevent.api; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Listener; + +import mineplex.core.common.util.UtilServer; + +public abstract class BossPassive, Y extends LivingEntity> implements Listener +{ + private T _creature; + private final int _cooldown; + + public BossPassive(T creature) + { + this(creature, 30); + } + + public BossPassive(T creature, int cooldown) + { + _creature = creature; + _cooldown = cooldown; + Bukkit.getPluginManager().registerEvents(this, UtilServer.getPlugin()); + } + + public abstract boolean isProgressing(); + + public abstract void tick(); + + public int getCooldown() + { + return _cooldown; + } + + public Y getEntity() + { + return getBoss().getEntity(); + } + + public T getBoss() + { + return _creature; + } + + public Location getLocation() + { + return getEntity().getLocation(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventArena.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventArena.java new file mode 100644 index 00000000..3169e953 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventArena.java @@ -0,0 +1,44 @@ +package mineplex.game.clans.clans.worldevent.api; + +import org.bukkit.Location; + +import mineplex.core.common.util.UtilMath; + +public class EventArena +{ + private final Location _centerLocation; + private final double _radius; + private final double _radiusSquared; + + public EventArena(Location center, double radius) + { + _centerLocation = center; + _radius = radius; + _radiusSquared = Math.pow(radius, 2); + } + + public Location getCenterLocation() + { + return _centerLocation; + } + + public double getRadius() + { + return _radius; + } + + public double getRadiusSquared() + { + return _radiusSquared; + } + + public boolean isInArena(Location checkLocation, boolean flat) + { + if (flat) + { + return UtilMath.offset2dSquared(checkLocation, _centerLocation) <= _radiusSquared; + } + + return UtilMath.offsetSquared(checkLocation, _centerLocation) <= _radiusSquared; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventCreature.java new file mode 100644 index 00000000..43326c03 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventCreature.java @@ -0,0 +1,412 @@ +package mineplex.game.clans.clans.worldevent.api; + +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.world.ChunkUnloadEvent; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.core.disguise.disguises.DisguiseBase; +import mineplex.core.disguise.disguises.DisguiseInsentient; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.condition.Condition.ConditionType; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public abstract class EventCreature implements Listener +{ + protected static final boolean DEBUG_MODE = true; + private static final long TELEPORT_HOME_WARMUP = 5000; + private static final long HEALTH_REGEN_COOLDOWN = 1500; + private static final long SAFE_TO_HEALTH_REGEN_COOLDOWN = 15000; + private static final double HEALTH_PER_REGEN = 1.5; + + private WorldEvent _event; + + // Spawn Data + private T _entity; + private Class _entityClass; + private Location _spawnLocation, _lastLocation; + + // Creature Data + private String _name; + private String _displayName; + private boolean _useName; + private double _health; + private double _maxHealth; + private boolean _showHealthName; + private long _teleportHome; + private double _walkRange; + private boolean _healthRegen; + + // Fight Data + private long _lastDamaged; + private UUID _lastDamager; + private long _lastRegen; + + public EventCreature(WorldEvent event, Location spawnLocation, String name, boolean useName, double health, double walkRange, boolean healthRegen, Class entityClass) + { + _event = event; + + _entityClass = entityClass; + _spawnLocation = spawnLocation; + + _name = name; + _displayName = name; + _useName = useName; + _health = health; + _maxHealth = health; + _showHealthName = true; + _teleportHome = -1L; + _walkRange = walkRange; + _healthRegen = healthRegen; + } + + public double getDifficulty() + { + return getEvent().getDifficulty(); + } + + protected void spawnEntity() + { + Location spawnLocation = _entity == null ? _spawnLocation : _entity.getLocation(); + T entity = _spawnLocation.getWorld().spawn(spawnLocation, getEntityClass()); + + setEntity(entity); + updateEntityHealth(); + entity.setRemoveWhenFarAway(false); + spawnCustom(); + updateName(); + } + + protected abstract void spawnCustom(); + + protected void updateEntityHealth() + { + _entity.setMaxHealth(500d); + _entity.setHealth(500d); + } + + protected void updateName() + { + String name = _displayName; + + if (_showHealthName) + { + String healthString = (int) _health + "/" + (int) _maxHealth; + double per =_health / _maxHealth; + if (per > 0.5) healthString = C.cGreen + healthString; + if (per > 0.2) healthString = C.cYellow + healthString; + else healthString = C.cRed + healthString; + + name += " " + C.cWhite + "(" + healthString + C.cWhite + ")"; + } + + DisguiseBase disguise = getEvent().getDisguiseManager().getActiveDisguise(getEntity()); + + if (disguise != null && disguise instanceof DisguiseInsentient) + { + ((DisguiseInsentient) disguise).setName(name); + ((DisguiseInsentient) disguise).setCustomNameVisible(_useName); + } + + _entity.setCustomName(name); + _entity.setCustomNameVisible(_useName); + } + + public void remove() + { + remove(true); + } + + public void remove(boolean removeFromEvent) + { + if (_entity != null) + { + if (getHealth() > 0) + { + _entity.remove(); + } + else + { + _entity.setHealth(0); + _entity.setCustomName(""); + _entity.setCustomNameVisible(false); + } + } + + if (removeFromEvent) + { + _event.removeCreature(this); + } + } + + protected final void die() + { + dieCustom(); + remove(); + } + + public abstract void dieCustom(); + + public WorldEvent getEvent() + { + return _event; + } + + public void setEvent(WorldEvent event) + { + _event = event; + } + + public T getEntity() + { + return _entity; + } + + public void setEntity(T entity) + { + if (_entity != null) _entity.remove(); + + _entity = entity; + } + + public Class getEntityClass() + { + return _entityClass; + } + + public void setEntityClass(Class clazz) + { + _entityClass = clazz; + } + + public double getHealthPercent() + { + return getHealth() / getMaxHealth(); + } + + public Location getSpawnLocation() + { + return _spawnLocation; + } + + public Location getLastKnownLocation() + { + return _lastLocation; + } + + public void setSpawnLocation(Location spawnLocation) + { + _spawnLocation = spawnLocation; + } + + public String getDisplayName() + { + return _displayName; + } + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _displayName = name == null ? _name : name; + updateName(); + } + + public boolean isUseName() + { + return _useName; + } + + public void setUseName(boolean useName) + { + _useName = useName; + updateName(); + } + + public void applyDamage(double damage) + { + setHealth(getHealth() - damage); + } + + public void applyRegen(double regen) + { + setHealth(getHealth() + regen); + } + + public double getHealth() + { + return _health; + } + + public void setHealth(double health) + { + _health = Math.min(health, getMaxHealth()); + + if (_health <= 0) + { + die(); + } + else + { + updateName(); + } + } + + public double getMaxHealth() + { + return _maxHealth; + } + + public void setMaxHealth(double maxHealth) + { + _maxHealth = maxHealth; + } + + public void setShowHealthName(boolean showHealthName) + { + _showHealthName = showHealthName; + updateName(); + } + + /** + * Event listeners + */ + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) + { + if (_entity != null && _entity.getLocation().getChunk().equals(event.getChunk())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + if (_entity == null || _entity.isDead() || !_entity.isValid()) + { + if (DEBUG_MODE) + { + System.out.println("Respawning " + getName() + " because it is null or dead"); + } + spawnEntity(); + } + + if (_healthRegen && getHealth() < getMaxHealth() && UtilTime.elapsed(_lastDamaged, SAFE_TO_HEALTH_REGEN_COOLDOWN) && UtilTime.elapsed(_lastRegen, HEALTH_REGEN_COOLDOWN)) + { + _lastRegen = System.currentTimeMillis(); + applyRegen(HEALTH_PER_REGEN); + } + + if (_walkRange != -1 && UtilMath.offset2d(_entity.getLocation(), _spawnLocation) > _walkRange) + { + if (_teleportHome != -1 && System.currentTimeMillis() >= _teleportHome) + { + _entity.teleport(_spawnLocation); + _teleportHome = -1; + } + else + { + _entity.setVelocity(UtilAlg.getTrajectory(_entity.getLocation(), _spawnLocation).normalize().multiply(2)); + if (_teleportHome == -1) + { + _teleportHome = System.currentTimeMillis() + TELEPORT_HOME_WARMUP; + } + } + } + else + { + if (_teleportHome != -1) + { + _teleportHome = -1; + } + } + + _lastLocation = _entity.getLocation(); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onDamage(CustomDamageEvent event) + { + if (_entity == null) + { + return; + } + + if (!event.GetDamageeEntity().equals(_entity)) + { + return; + } + + updateEntityHealth(); + + applyDamage(event.GetDamage()); + updateName(); + + _lastDamaged = System.currentTimeMillis(); + + _event.updateLastActive(); + } + + @EventHandler + public void damageType(CustomDamageEvent event) + { + if (_entity == null) + { + return; + } + + if (!event.GetDamageeEntity().equals(_entity)) + { + return; + } + + DamageCause cause = event.GetCause(); + + if (cause == DamageCause.FALL && !getEvent().getCondition().HasCondition(_entity, ConditionType.FALLING, null)) + { + event.SetCancelled("Cancel"); + } + + if (cause == DamageCause.DROWNING || cause == DamageCause.SUFFOCATION) + { + event.SetCancelled("Cancel"); + } + } + + @EventHandler + public void cancelCombust(EntityCombustEvent event) + { + if (_entity == null) + { + return; + } + + if (!event.getEntity().equals(_entity)) + { + return; + } + + event.setCancelled(true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventCreatureDeathEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventCreatureDeathEvent.java new file mode 100644 index 00000000..8141b474 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventCreatureDeathEvent.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.clans.worldevent.api; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class EventCreatureDeathEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private final EventCreature _creature; + + public EventCreatureDeathEvent(EventCreature creature) + { + _creature = creature; + } + + public EventCreature getCreature() + { + return _creature; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventState.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventState.java new file mode 100644 index 00000000..bdee5445 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/EventState.java @@ -0,0 +1,9 @@ +package mineplex.game.clans.clans.worldevent.api; + +public enum EventState +{ + LOADING, + LIVE, + STOPPED, + REMOVED +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/WorldEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/WorldEvent.java new file mode 100644 index 00000000..aa80d730 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/api/WorldEvent.java @@ -0,0 +1,342 @@ + package mineplex.game.clans.clans.worldevent.api; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.blockrestore.BlockRestoreMap; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.projectile.ProjectileManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +public abstract class WorldEvent implements Listener, ScoreboardElement +{ + // 30 Minutes + private static final int ACTIVE_TIMEOUT = 1800000; + private static final int LOADING_TIMEOUT = 300000; + + private DamageManager _damageManager; + private ConditionManager _conditionManager; + private DisguiseManager _disguiseManager; + private ProjectileManager _projectileManager; + + private String _name; + private EventState _state; + private EventArena _arena; + private Random _random; + private long _timeStarted; + private long _lastActive; + private boolean _announceStart; + + // Creatures + private List> _creatures; + // Block Restore + private BlockRestoreMap _blockRestoreMap; + private double _difficulty = 1; + + public WorldEvent(String name, Location centerLocation, double radius, boolean announceStart, DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager) + { + _disguiseManager = disguiseManager; + _projectileManager = projectileManager; + _damageManager = damageManager; + _conditionManager = conditionManager; + + _name = name; + _state = EventState.LOADING; + _arena = new EventArena(centerLocation, radius); + _random = new Random(); + _announceStart = announceStart; + + _creatures = new ArrayList<>(); + _blockRestoreMap = blockRestore.createMap(); + } + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _name = name; + } + + public EventArena getEventArena() + { + return _arena; + } + + public EventState getState() + { + return _state; + } + + protected void setState(EventState state) + { + _state = state; + } + + public double getDifficulty() + { + return _difficulty; + } + + public void setDifficulty(double difficulty) + { + _difficulty = difficulty; + } + + public boolean allowsIcePrison() + { + return false; + } + + public Location getCenterLocation() + { + return _arena.getCenterLocation(); + } + + public List> getCreatures() + { + return _creatures; + } + + public void registerCreature(EventCreature creature) + { + UtilServer.RegisterEvents(creature); + _creatures.add(creature); + } + + public void removeCreature(EventCreature creature) + { + Bukkit.getPluginManager().callEvent(new EventCreatureDeathEvent(creature)); + HandlerList.unregisterAll(creature); + _creatures.remove(creature); + } + + public void clearCreatures() + { + for (EventCreature creature : _creatures) + { + creature.remove(false); + HandlerList.unregisterAll(creature); + } + + _creatures.clear(); + } + + public long getTimeRunning() + { + return System.currentTimeMillis() - _timeStarted; + } + + public long getLastActive() + { + return _lastActive; + } + + public void updateLastActive() + { + _lastActive = System.currentTimeMillis(); + } + + public boolean isInBounds(Location location, boolean flat) + { + return _arena.isInArena(location, flat); + } + + protected Random getRandom() + { + return _random; + } + + public DisguiseManager getDisguiseManager() + { + return _disguiseManager; + } + + public ProjectileManager getProjectileManager() + { + return _projectileManager; + } + + public DamageManager getDamageManager() + { + return _damageManager; + } + + public ConditionManager getCondition() + { + return _conditionManager; + } + + protected BlockRestoreMap getBlockRestoreMap() + { + return _blockRestoreMap; + } + + public void setBlock(Block block, Material material) + { + setBlock(block, material, (byte) 0); + } + + @SuppressWarnings("deprecation") + public void setBlock(Block block, Material material, byte data) + { + setBlock(block, material.getId(), data); + } + + public void setBlock(Block block, int id, byte data) + { + _blockRestoreMap.set(block, id, data); + } + + public void restoreBlocks() + { + _blockRestoreMap.restore(); + } + + public final void start() + { + _timeStarted = System.currentTimeMillis(); + _lastActive = System.currentTimeMillis(); + if (_announceStart) + { + announceStart(); + } + setState(EventState.LIVE); + customStart(); + UtilServer.RegisterEvents(this); + } + + public void announceStart() + { + UtilTextMiddle.display(C.cGreen + getName(), UtilWorld.locToStrClean(getCenterLocation()), 10, 100, 40); + + UtilServer.broadcast(F.main("Event", F.elem(getName()) + " has started at coordinates " + F.elem(UtilWorld.locToStrClean(getCenterLocation())))); + } + + protected abstract void customStart(); + + protected abstract void customTick(); + + public final void cleanup(boolean onDisable) + { + clearCreatures(); + restoreBlocks(); + customCleanup(onDisable); + } + + public abstract void customCleanup(boolean onDisable); + + public final void stop() + { + stop(false); + } + + public final void stop(boolean onDisable) + { + cleanup(onDisable); + if (onDisable) + { + setState(EventState.REMOVED); + } + else + { + setState(EventState.STOPPED); + } + customStop(); + HandlerList.unregisterAll(this); + } + + protected abstract void customStop(); + + public int getRandomRange(int min, int max) + { + return min + _random.nextInt(UtilMath.clamp(max - min, min, max)); + } + + public void announceMessage(String message) + { + UtilServer.broadcast(F.main("Event", F.elem(getName()) + ": " + message)); + } + + public void sendMessage(Player player, String message) + { + UtilPlayer.message(player, F.main("Event", F.elem(getName()) + ": " + message)); + } + + @EventHandler + public void tick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + customTick(); + } + + @EventHandler + public void endInactive(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + long diff = System.currentTimeMillis() - getLastActive(); + if (diff > ACTIVE_TIMEOUT) + { + stop(); + } + } + + @EventHandler + public void prepareTimeout(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + if (getState() != EventState.LOADING) + { + return; + } + + // Event was preparing for more than 5 minutes + if (getTimeRunning() > LOADING_TIMEOUT) + { + stop(); + } + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + return null; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossArenaLocationFinder.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossArenaLocationFinder.java new file mode 100644 index 00000000..a4c6bbc6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossArenaLocationFinder.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.clans.worldevent.boss; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.util.Vector; + +import mineplex.core.common.Pair; + +public class BossArenaLocationFinder +{ + private World _world; + + public BossArenaLocationFinder(World world) + { + _world = world; + } + + public Location getIronWizardCenter() + { + return new Location(_world, 1057, 63, -77); + } + + public Pair, List> getIronWizardPads() + { + List in = new ArrayList<>(); + List out = new ArrayList<>(); + + in.add(new Vector(1006, 62, -77)); + in.add(new Vector(1057, 62, -26)); + in.add(new Vector(1108, 62, -77)); + in.add(new Vector(1057, 62, -128)); + + out.add(new Vector(1035, 63, -77)); + out.add(new Vector(1057, 63, -99)); + out.add(new Vector(1079, 63, -77)); + out.add(new Vector(1057, 63, -55)); + + return Pair.create(in, out); + } + + public Location getSkeletonKingCenter() + { + return new Location(_world, -1043, 58, 159); + } + + public Pair, List> getSkeletonKingPads() + { + List in = new ArrayList<>(); + List out = new ArrayList<>(); + + in.add(new Vector(-1094, 57, 159)); + in.add(new Vector(-1043, 57, 210)); + in.add(new Vector(-992, 57, 159)); + in.add(new Vector(-1043, 57, 108)); + + out.add(new Vector(-1021, 58, 159)); + out.add(new Vector(-1043, 58, 137)); + out.add(new Vector(-1065, 58, 159)); + out.add(new Vector(-1043, 58, 181)); + + return Pair.create(in, out); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossDeathEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossDeathEvent.java new file mode 100644 index 00000000..cb4e76ed --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossDeathEvent.java @@ -0,0 +1,39 @@ +package mineplex.game.clans.clans.worldevent.boss; + +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class BossDeathEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + private final BossWorldEvent _event; + private final Location _deathLocation; + + public BossDeathEvent(BossWorldEvent event, Location location) + { + _event = event; + _deathLocation = location; + } + + public BossWorldEvent getEvent() + { + return _event; + } + + public Location getDeathLocation() + { + return _deathLocation; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossWorldEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossWorldEvent.java new file mode 100644 index 00000000..1fdf45bd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/BossWorldEvent.java @@ -0,0 +1,129 @@ +package mineplex.game.clans.clans.worldevent.boss; + +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.projectile.ProjectileManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.minecraft.game.classcombat.Skill.ISkill; +import mineplex.minecraft.game.classcombat.Skill.Assassin.Blink; +import mineplex.minecraft.game.classcombat.Skill.Assassin.Recall; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +public abstract class BossWorldEvent> extends WorldEvent +{ + private static final double TELEPORT_PAD_RANGE = 1.5; + private static final long DELAY_TILL_DROP_REWARD = 40; + + private T _boss; + private List _teleportFrom; + private List _teleportTo; + + public BossWorldEvent(String name, Location centerLocation, double radius, List teleportFrom, List teleportTo, DisguiseManager disguiseManager, ProjectileManager projectileManager, DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager) + { + super(name, centerLocation, radius, true, disguiseManager, projectileManager, damageManager, blockRestore, conditionManager); + + _teleportFrom = teleportFrom.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList()); + _teleportTo = teleportTo.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList()); + } + + public abstract String getDeathMessage(); + + public T getBossCreature() + { + return _boss; + } + + public void setBossCreature(T boss) + { + _boss = boss; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (getState() != EventState.LIVE) + { + return; + } + if (_teleportFrom.isEmpty() || _teleportTo.isEmpty()) + { + return; + } + for (Location from : _teleportFrom) + { + for (Player player : UtilPlayer.getInRadius(from, TELEPORT_PAD_RANGE).keySet()) + { + if (ClansManager.getInstance().hasTimer(player)) + { + if (Recharge.Instance.use(player, "PvP Timer Inform NoBoss", 5000, false, false)) + { + UtilPlayer.message(player, F.main(getName(), "You cannot enter a World Boss whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + } + continue; + } + player.teleport(UtilMath.randomElement(_teleportTo)); + for (ISkill skill : ClansManager.getInstance().getClassManager().Get(player).GetSkills()) + { + if (skill instanceof Recall) + { + ((Recall)skill).Reset(player); + } + if (skill instanceof Blink) + { + ((Blink)skill).Reset(player); + } + } + sendMessage(player, "You have teleported inside the arena!"); + } + } + } + + @EventHandler + public void onBossDeath(EventCreatureDeathEvent event) + { + if (_boss == null) + { + return; + } + if (event.getCreature().equals(_boss)) + { + Location drop = event.getCreature().getLastKnownLocation(); + UtilServer.CallEvent(new BossDeathEvent(this, drop)); + ClansManager.getInstance().runSyncLater(() -> + { + ClansManager.getInstance().getLootManager().dropBoss(drop); + drop.getWorld().dropItem(drop, new ItemBuilder(Material.IRON_INGOT).setTitle(C.cDRedB + "Old Silver Token").setLore(C.cRed + "This token pulses with an evil aura.").setGlow(true).build()); + }, DELAY_TILL_DROP_REWARD); + Bukkit.broadcastMessage(getDeathMessage()); + stop(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/GolemBoss.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/GolemBoss.java new file mode 100644 index 00000000..2d79eea2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/GolemBoss.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +import mineplex.core.common.util.F; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.boss.BossWorldEvent; + +public class GolemBoss extends BossWorldEvent +{ + public GolemBoss(WorldEventManager manager) + { + super("Iron Wizard", manager.getBossArenaLocationFinder().getIronWizardCenter(), 50, manager.getBossArenaLocationFinder().getIronWizardPads().getLeft(), manager.getBossArenaLocationFinder().getIronWizardPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition()); + } + + @Override + protected void customStart() + { + Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " challenges you to face him!")); + spawnGolem(getCenterLocation()); + } + + @Override + public String getDeathMessage() + { + return F.main(getName(), "The mighty " + getName() + " has fallen!"); + } + + private GolemCreature spawnGolem(Location location) + { + GolemCreature golemCreature = new GolemCreature(this, location); + registerCreature(golemCreature); + setBossCreature(golemCreature); + return golemCreature; + } + + @Override + protected void customTick() {} + + @Override + public void customCleanup(boolean onDisable) {} + + @Override + protected void customStop() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/GolemCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/GolemCreature.java new file mode 100644 index 00000000..216ede26 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/GolemCreature.java @@ -0,0 +1,599 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemBlockHail; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemBlockShot; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemDeadlyTremor; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemEarthquake; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemExplodingAura; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemIronHook; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemMeleeAttack; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemRupture; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemSlam; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemSpike; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class GolemCreature extends EventCreature +{ + private int _lastAbility; + private long _lastWalked; + private Location _standing; + private long _spawnDelay = System.currentTimeMillis(); + private long _reverseWalk; + private Map>, Class[]> _preferredCombos = new HashMap<>(); + private Class> _lastAttack; + private boolean _usedFinalAttack; + private List> _currentAbilities = new ArrayList<>(); + private double _canDeadlyTremor = 225; + private Vector _afkWalk = new Vector(); + private long _lastSlam; + + public GolemCreature(GolemBoss boss, Location location) + { + super(boss, location, "Iron Wizard", true, 3000, 30, true, IronGolem.class); + + spawnEntity(); + + _preferredCombos.put(GolemEarthquake.class, new Class[] + { + GolemBlockHail.class, GolemRupture.class + }); + _preferredCombos.put(GolemMeleeAttack.class, new Class[] + { + GolemEarthquake.class, GolemRupture.class + }); + _preferredCombos.put(GolemDeadlyTremor.class, new Class[] + { + GolemMeleeAttack.class + }); + _preferredCombos.put(GolemBlockShot.class, new Class[] + { + GolemEarthquake.class + }); + _preferredCombos.put(GolemRupture.class, new Class[] + { + GolemBlockShot.class + }); + _preferredCombos.put(GolemBlockHail.class, new Class[] + { + GolemDeadlyTremor.class + }); + } + + private boolean hasFurther(Map distances, double range) + { + for (Player player : distances.keySet()) + { + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + + Double dist = distances.get(player); + if (dist >= range) + { + return true; + } + } + + return false; + } + + @Override + protected void spawnCustom() + { + UtilEnt.vegetate(getEntity()); + _standing = getEntity().getLocation(); + } + + @SuppressWarnings("unchecked") + @EventHandler + public void abilityTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (!UtilTime.elapsed(_spawnDelay, 5000)) + { + _standing = getEntity().getLocation(); + return; + } + + Iterator> itel = _currentAbilities.iterator(); + boolean canDoNew = _currentAbilities.size() < 3; + + while (itel.hasNext()) + { + BossAbility ability = itel.next(); + + if (ability.hasFinished()) + { + itel.remove(); + ability.setFinished(); + _lastAbility = 20; + + HandlerList.unregisterAll(ability); + if (DEBUG_MODE) + { + System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName()); + } + } + else if (!ability.inProgress()) + { + canDoNew = false; + } + } + + if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN))) + { + Map>, Integer> weight = new HashMap<>(); + Map dist = new HashMap<>(); + + for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true)) + { + if (player.hasLineOfSight(getEntity())) + { + dist.put(player, player.getLocation().distance(getEntity().getLocation())); + } + } + + if (!dist.isEmpty()) + { + double hp = getHealthPercent(); + + { // Melee + List players = getPlayers(dist, UtilMath.r(10) == 0 ? 4 : 3); + + if (!players.isEmpty()) + { + if (players.size() >= 4) + { + weight.put(GolemEarthquake.class, 999); + } + else + { + weight.put(GolemMeleeAttack.class, 999); + } + } + } + + if (hasFurther(dist, 15)) + { // Iron Hook + weight.put(GolemIronHook.class, 6); //6 + } + + if (hp < 0.7) + { // Earthquake + List players = getPlayers(dist, 10); + + double score = 0; + + for (Player player : players) + { + score += (8 - dist.get(player)) / 2; + } + + if (players.size() >= 3) + { + score += 7; + } + + if (score > 0) + { + weight.put(GolemEarthquake.class, (int) Math.ceil(score)); + } + } + + { // Wall explode + if (!getPlayers(dist, 20).isEmpty() && getPlayers(dist, 4).isEmpty()) + { + weight.put(GolemSpike.class, 8); + } + } + + { // Block Shot + List players = getPlayers(dist, 30); + + for (Player player : players) + { + if (dist.get(player) > 4) + { + weight.put(GolemBlockShot.class, 6); + break; + } + } + } + + { // Rupture + List players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + weight.put(GolemRupture.class, (int) Math.min(5, dist.get(players.get(0)))); + } + } + + { // Slam + List players = getPlayers(dist, 30); + + if (!players.isEmpty() && UtilTime.elapsed(_lastSlam, 20000)) + { + weight.put(GolemSlam.class, 6); + } + } + + if (_canDeadlyTremor <= 0) // Deadly Tremor + { + List players = getPlayers(dist, 80); + + for (BossAbility ability : _currentAbilities) + { + if (ability instanceof GolemExplodingAura) + { + players.clear(); + } + } + + if (!players.isEmpty()) + { + weight.put(GolemDeadlyTremor.class, (int) 30); + } + } + + {// Block Hail + List players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + int we = _lastAttack == GolemEarthquake.class ? 20 : UtilMath.r(15) - 2; + + if (we > 0) + { + weight.put(GolemBlockHail.class, we); + } + } + } + + if (!_usedFinalAttack && getHealth() < 90) + { + _usedFinalAttack = true; + weight.clear(); + + weight.put(GolemExplodingAura.class, 999); + } + + if (_lastAttack != null && _preferredCombos.containsKey(_lastAttack)) + { + weight.remove(_lastAttack); + + for (Class c : _preferredCombos.get(_lastAttack)) + { + if (weight.containsKey(c)) + { + weight.put((Class>)c, weight.get(c) * 4); + } + } + } + + for (BossAbility ability : _currentAbilities) + { + weight.remove(ability.getClass()); + } + + BossAbility ability = null; + + if (!weight.isEmpty()) + { + int i = 0; + + for (Integer entry : weight.values()) + { + i += entry; + } + + for (int a = 0; a < 10; a++) + { + int luckyNumber = UtilMath.r(i); + + for (Entry>, Integer> entry : weight.entrySet()) + { + luckyNumber -= entry.getValue(); + + if (luckyNumber <= 0) + { + try + { + ability = entry.getKey().getConstructor(GolemCreature.class).newInstance(this); + + if (ability.getTarget() == null) + { + ability = null; + } + else + { + break; + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + break; + } + } + } + } + + if (ability != null && ability.getTarget() != null) + { + _lastAttack = (Class>) ability.getClass(); + + if (ability instanceof GolemDeadlyTremor) + { + _canDeadlyTremor = 225; + } + else if (ability instanceof GolemSlam) + { + _lastSlam = System.currentTimeMillis(); + } + + Bukkit.getPluginManager().registerEvents(ability, UtilServer.getPlugin()); + + if (DEBUG_MODE) + { + System.out.print("Golem boss is using " + ability.getClass().getSimpleName()); + } + + _currentAbilities.add(ability); + } + + _lastAbility = 10; + } + + _lastAttack = null; + } + + boolean canMove = true; + + for (BossAbility ability : _currentAbilities) + { + try + { + ability.tick(); + } + catch (Exception e) + { + e.printStackTrace(); //Keeps the boss from getting stuck if one of the moves throws an error in progression + } + + if (!ability.canMove()) + { + canMove = false; + } + } + + if (canMove) + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getEntity().getLocation()); + + if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d))) + { + target = player; + dist = d; + } + } + + Vector vec = null; + boolean superWalk = false; + + if (target != null) + { + vec = target.getLocation().subtract(getEntity().getLocation()).toVector(); + vec.setY(getEntity().getLocation().getY()); + + double len = vec.length(); + + vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D)); + vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D)); + + vec.multiply(len); + + if (target != null && dist < 8) + { + vec.multiply(-1); + superWalk = true; + } + + if (!UtilAlg.HasSight(getEntity().getLocation(), + getEntity().getLocation().add(vec.clone().normalize().multiply(2)))) + { + _reverseWalk = System.currentTimeMillis(); + } + + if (!UtilTime.elapsed(_reverseWalk, 4000)) + { + vec.multiply(-1); + } + + } + else if (!UtilTime.elapsed(_lastWalked, 7000)) + { + vec = _afkWalk; + } + else if (UtilTime.elapsed(_lastWalked, 12000)) + { + _afkWalk = new Vector(); + + for (int i = 0; i < 10; i++) + { + Vector vector = new Vector(UtilMath.r(20) - 10, 0, UtilMath.r(20) - 10); + + if (UtilAlg.HasSight(getEntity().getLocation(), + getEntity().getLocation().add(vector.clone().normalize().multiply(2)))) + { + vec = _afkWalk = vector; + break; + } + } + + _lastWalked = System.currentTimeMillis(); + } + + if (vec != null) + { + { + UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec), + (target != null ? 1.8F : 1.1F) + (superWalk ? 0.4F : 0)); + } + } + + _standing = getEntity().getLocation(); + } + else + { + Location l = getEntity().getLocation(); + + _standing.setYaw(l.getYaw()); + _standing.setPitch(l.getPitch()); + _standing.setY(l.getY()); + + getEntity().teleport(_standing); + } + } + + private List getPlayers(final Map map, double maxDist) + { + List list = new ArrayList(); + + for (Player p : map.keySet()) + { + if (map.get(p) <= maxDist) + { + list.add(p); + } + } + + Collections.sort(list, (o1, o2) -> + { + return Double.compare(map.get(o2), map.get(o1)); + }); + + return list; + } + + @EventHandler + public void onGolemDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + event.AddKnockback("Heavy Golem", 0.3); + } + } + + @EventHandler + public void onRangedAttack(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + if (event.GetDamageePlayer() != null) + { + if (event.GetProjectile() != null && event.GetProjectile() instanceof Arrow) + { + if (new Random().nextDouble() <= .5) + { + event.SetCancelled("Iron Skin Reflection"); + getEntity().getWorld().playSound(getEntity().getLocation(), Sound.ZOMBIE_METAL, 0.5f, 1.6f); + return; + } + } + + double dist = event.GetDamageePlayer().getLocation().distance(getEntity().getLocation()); + + double maxRange = _usedFinalAttack ? 20 : 45; + + double modifier = (maxRange - dist) / maxRange; + + if (modifier > 0) + { + event.AddMod("Ranged Resistance", 1 - modifier); + } + else + { + event.SetCancelled("Range too far"); + } + } + } + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + for (BossAbility ability : _currentAbilities) + { + ability.setFinished(); + HandlerList.unregisterAll(ability); + } + + _currentAbilities.clear(); + } + + @Override + public void setHealth(double health) + { + _canDeadlyTremor -= getHealth() - health; + super.setHealth(health); + if (getHealth() <= 100 && !_usedFinalAttack) + { + endAbility(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/BlockHailBlock.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/BlockHailBlock.java new file mode 100644 index 00000000..d837321c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/BlockHailBlock.java @@ -0,0 +1,88 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.IronGolem; + +import mineplex.core.common.util.UtilEnt; +import net.minecraft.server.v1_8_R3.DataWatcher; +import net.minecraft.server.v1_8_R3.Entity; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; + +public class BlockHailBlock +{ + private int _block = UtilEnt.getNewEntityId(); + private int _silverfish = UtilEnt.getNewEntityId(); + private Location _location; + private Material _mat; + + public BlockHailBlock(Location loc, Material mat) + { + _location = loc; + _mat = mat; + } + + public PacketPlayOutEntityDestroy getDestroyPacket() + { + return new PacketPlayOutEntityDestroy(new int[] + { + _silverfish, _block + }); + } + + public Location getLocation() + { + return _location; + } + + public Material getMaterial() + { + return _mat; + } + + @SuppressWarnings("deprecation") + public Packet[] getSpawnPackets(IronGolem entity) + { + Packet[] packets = new Packet[3]; + + PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving(); + + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32, Entity.META_ENTITYDATA, (byte) 0); + watcher.a(1, 0, Entity.META_AIR, 0); + + packet1.a = _silverfish; + packet1.b = EntityType.SILVERFISH.getTypeId(); + packet1.c = (int) Math.floor(_location.getX() * 32); + packet1.d = (int) Math.floor(_location.getY() * 32); + packet1.e = (int) Math.floor(_location.getZ() * 32); + packet1.l = watcher; + + packets[0] = packet1; + + PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, _mat.getId()); + + packet2.a = _block; + + packet2.b = (int) Math.floor(_location.getX() * 32); + packet2.c = (int) Math.floor(entity.getLocation().getY() * 32); + packet2.d = (int) Math.floor(_location.getZ() * 32); + + packets[1] = packet2; + + PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); + + packet3.b = _block; + packet3.c = _silverfish; + + packets[2] = packet3; + + return packets; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemBlockHail.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemBlockHail.java new file mode 100644 index 00000000..99c43777 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemBlockHail.java @@ -0,0 +1,475 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; +import net.minecraft.server.v1_8_R3.EntityIronGolem; +import net.minecraft.server.v1_8_R3.MathHelper; +import net.minecraft.server.v1_8_R3.MovingObjectPosition; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.Vec3D; + +public class GolemBlockHail extends BossAbility +{ + private int _currentBlock; + private int _currentLevel; + private List _fallingBlocks = new ArrayList<>(); + private Map> _floatingBlocks = new HashMap<>(); + private Map _blocks = new HashMap<>(); + private int _levelToReach; + private boolean _spawned; + private List _spawnLocs = new ArrayList<>(); + private Player _target; + private Location _center; + private int _ticks; + + public GolemBlockHail(GolemCreature creature) + { + super(creature); + + _center = getLocation(); + + if (creature.getHealthPercent() > 0.75) + { + _levelToReach = 1; + } + else if (creature.getHealthPercent() > 0.5) + { + _levelToReach = 2; + } + else + { + _levelToReach = 3; + } + + _target = getTarget(); + } + + @Override + public Player getTarget() + { + Player target = null; + double dist = 0; + + if (inProgress()) + { + for (Player player : UtilPlayer.getNearby(_center, 40, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + if (target != null && _blocks.containsKey(player.getName()) && _blocks.get(player.getName()) > 8) + { + continue; + } + + double d = player.getLocation().distance(_center); + + if (target == null || dist > d) + { + target = player; + dist = d; + } + } + } + + return target; + } + + @Override + public boolean canMove() + { + return _spawned && _floatingBlocks.isEmpty(); + } + + @Override + public boolean hasFinished() + { + return _target == null || !_target.isValid() || ((_fallingBlocks.isEmpty() && _spawned) && _ticks >= 8 * 9) + || _center.distance(_target.getLocation()) > 100; + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, + nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + { + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null, + DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Hail", + "Iron Wizard Block Hail"); + } + + if (victim instanceof Player) + { + getBoss().getEvent().getCondition().Factory().Slow("Iron Wizard Block Hail", (LivingEntity) victim, + getEntity(), 3, 2, false, false, false, false); + } + + fallingIterator.remove(); + cur.remove(); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c)); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt( + nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + fallingIterator.remove(); + cur.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (List floatingBlocks : _floatingBlocks.values()) + { + for (BlockHailBlock falling : floatingBlocks) + { + PacketPlayOutEntityDestroy packet = falling.getDestroyPacket(); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + } + } + + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + } + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + if (inProgress()) + { + for (Player player : UtilPlayer.getNearby(_center, 5, true)) + { + Location loc = player.getLocation(); + + if (Math.abs(loc.getY() - (_center.getY() + 1)) <= 1) + { + loc.setY(_center.getY()); + + if (loc.distance(_center) < 2.8 + (_currentLevel * 0.75)) + { + if (canDamage(player)) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, + DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, + "Iron Wizard Protection", "Iron Wizard Protection"); + + loc.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId()); + loc.getWorld().playEffect(player.getEyeLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId()); + } + } + } + } + } + + if (!_spawned) + { + if (_currentBlock >= _spawnLocs.size()) + { + + if (_currentLevel + 1 <= _levelToReach) + { + _currentLevel++; + _currentBlock = 0; + + _spawnLocs = UtilShapes.getDistancedCircle(_center.clone().add(0, 2.8 + (_currentLevel * 0.75), 0), 1.3, + 1 + (_currentLevel * 1.3)); + + for (int i = UtilMath.r(_spawnLocs.size()); i > 0; i--) + { + _spawnLocs.add(_spawnLocs.remove(0)); + } + } + } + + if (_currentBlock < _spawnLocs.size()) + { + if (_ticks % 2 == 0) + { + IronGolem entity = getEntity(); + + Location loc = _spawnLocs.get(_currentBlock++); + + List floatingBlocks = new ArrayList<>(); + + if (_floatingBlocks.containsKey(_currentLevel)) + { + floatingBlocks = _floatingBlocks.get(_currentLevel); + } + else + { + _floatingBlocks.put(_currentLevel, floatingBlocks); + } + + if (loc.getBlock().getType() == Material.AIR && UtilAlg.HasSight(entity.getLocation(), loc)) + { + + BlockHailBlock floating = new BlockHailBlock(loc, Material.STONE); + UtilEnt.CreatureLook(entity, _target); + + floatingBlocks.add(floating); + + Packet[] packets = floating.getSpawnPackets(entity); + + for (Player player : UtilPlayer.getNearby(loc, 100)) + { + UtilPlayer.sendPacket(player, packets); + } + + entity.getWorld().playSound(entity.getLocation(), Sound.DIG_GRASS, 3, 0.9F); + } + + if (_floatingBlocks.size() % 2 == 0) + { + Collections.reverse(floatingBlocks); + } + } + } + else + { + _spawned = true; + _ticks = -20; + } + } + else if (_ticks > 0 && _ticks % 2 == 0 && !_floatingBlocks.isEmpty()) + { + IronGolem entity = getEntity(); + + if (_ticks % 16 == 0) + { + _target = getTarget(); + + if (_target == null) + return; + } + + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + UtilEnt.CreatureLook(entity, _target); + + BlockHailBlock floatingBlock = null; + + for (int i = 1; i <= _currentLevel; i++) + { + if (_floatingBlocks.containsKey(i) && !_floatingBlocks.get(i).isEmpty()) + { + floatingBlock = _floatingBlocks.get(i).remove(0); + + if (_floatingBlocks.get(i).isEmpty()) + { + _floatingBlocks.remove(i); + } + + break; + } + } + + PacketPlayOutEntityDestroy packet = floatingBlock.getDestroyPacket(); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + Location loc = floatingBlock.getLocation(); + + FallingBlock b = loc.getWorld().spawnFallingBlock(loc, floatingBlock.getMaterial(), (byte) 0); + b.setDropItem(false); + + Vector vec = UtilAlg.calculateVelocity(loc.toVector(), + _target.getLocation().toVector().add(new Vector(UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel), 0, + UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel))), + 6); + + b.setVelocity(vec); + + _fallingBlocks.add(b); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F); + + _blocks.put(_target.getName(), _blocks.containsKey(_target.getName()) ? _blocks.get(_target.getName()) + 1 : 1); + } + + List points = new ArrayList<>(); + + for (int i = _currentLevel; i <= _currentLevel; i++) + { + points.addAll(UtilShapes.getDistancedCircle(_center.clone().add(0, 3.3 + (i * 0.75), 0), 0.3, 1 + (i * 1.3))); + } + + for (int i = 0; i < points.size(); i++) + { + if (_spawned || i < _ticks) + { + Location loc = points.get(i); + + UtilParticle.PlayParticle( + ParticleType.BLOCK_DUST.getParticle(_spawned && i < _ticks ? Material.STONE : Material.DIRT, 0), loc, 0, + 0, 0, 0, 0, UtilParticle.ViewDist.LONG, UtilServer.getPlayers()); + } + } + + _ticks++; + } + + @Override + public boolean inProgress() + { + return !_spawned || !_floatingBlocks.isEmpty(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemBlockShot.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemBlockShot.java new file mode 100644 index 00000000..4f652b4a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemBlockShot.java @@ -0,0 +1,442 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; +import net.minecraft.server.v1_8_R3.EntityIronGolem; +import net.minecraft.server.v1_8_R3.MathHelper; +import net.minecraft.server.v1_8_R3.MovingObjectPosition; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityVelocity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_8_R3.Vec3D; + +public class GolemBlockShot extends BossAbility +{ + private Map _blockLoc = new HashMap<>(); + private Map _blockType = new HashMap<>(); + private List _current = new ArrayList<>(); + private Map _preshoot = new HashMap<>(); + private Player _target; + private Map _targetBlock = new HashMap<>(); + private Map _shotAt = new HashMap<>(); + private int _thrown; + private int _tick; + private int _toThrow; + + public GolemBlockShot(GolemCreature creature) + { + super(creature); + + if (creature.getHealthPercent() > 0.75) + { + _toThrow = 3; + } + else if (creature.getHealthPercent() > 0.5) + { + _toThrow = 6; + } + else + { + _toThrow = 9; + } + + _target = getTarget(); + } + + @Override + public boolean canMove() + { + return _current.isEmpty() && _thrown == _toThrow; + } + + @Override + public Player getTarget() + { + Player target = null; + double dist = 0; + + Location loc1 = getLocation(); + Location loc2 = loc1.clone().add(loc1.getDirection().setY(0).normalize()); + + List players = UtilPlayer.getNearby(getLocation(), 40, true); + + for (Player player : players) + { + if (_shotAt.containsKey(player.getUniqueId()) && _shotAt.get(player.getUniqueId()) >= 3) + { + continue; + } + + double dist1 = player.getLocation().distance(loc1); + double dist2 = player.getLocation().distance(loc2); + + double dist3 = dist1 - dist2; + + if (dist3 < 0.6 || dist1 > 30 || (target != null && dist3 < dist)) + { + continue; + } + + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + target = player; + dist = dist3; + } + + return target; + } + + @Override + public boolean hasFinished() + { + return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown >= _toThrow); + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _current.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, + nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null, + DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Shot", + "Iron Wizard Block Shot"); + + cur.remove(); + fallingIterator.remove(); + + Vector vec = UtilAlg.getTrajectory(getEntity(), victim); + vec.setY(0).normalize(); + + double strength = 1; + + if (!(victim instanceof Player) || !((Player) victim).isBlocking()) + { + strength = 1.3; + } + + UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c)); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt( + nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + cur.remove(); + fallingIterator.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (FallingBlock falling : _current) + { + falling.remove(); + } + + int[] ids = new int[_preshoot.size()]; + + int a = 0; + for (int id : _preshoot.keySet()) + { + ids[a++] = id; + } + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + } + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + if (_target == null || _target.getLocation().distance(getLocation()) > 30 || !_target.hasLineOfSight(getEntity())) + { + _target = getTarget(); + } + + Entity entity = getEntity(); + + if (_tick++ % 16 == 0 && _target != null && _thrown < _toThrow) + { + _thrown++; + + UtilEnt.CreatureLook(entity, _target); + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1); + + Location loc = entity.getLocation(); + loc.setYaw(loc.getYaw() + (UtilMath.r(150) - 75)); + loc.add(loc.getDirection().setY(0).normalize()); + + Block block = loc.getBlock(); + + if (block.getType() == Material.AIR) + { + block = block.getRelative(BlockFace.DOWN); + } + + Material mat = block.getType(); + + if (!UtilBlock.solid(block)) + { + mat = Material.STONE; + } + + int id = UtilEnt.getNewEntityId(); + + _preshoot.put(id, System.currentTimeMillis()); + _blockType.put(id, mat); + _blockLoc.put(id, loc.clone().add(0, 0.6, 0)); + _targetBlock.put(id, _target); + + PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, mat.getId()); + + packet.a = id; + + packet.b = (int) Math.floor(loc.getX() * 32); + packet.c = (int) Math.floor(loc.getY() * 32); + packet.d = (int) Math.floor(loc.getZ() * 32); + + packet.g = (int) ((0.45) * 8000); + + PacketPlayOutEntityVelocity packet2 = new PacketPlayOutEntityVelocity(id, 0, 0.45D, 0); + + for (Player player : UtilPlayer.getNearby(loc, 70)) + { + UtilPlayer.sendPacket(player, packet, packet2); + } + + _shotAt.put(_target.getUniqueId(), + (_shotAt.containsKey(_target.getUniqueId()) ? _shotAt.get(_target.getUniqueId()) : 0) + 1); + + _target = getTarget(); + } + else + { + Iterator> itel = _preshoot.entrySet().iterator(); + + while (itel.hasNext()) + { + Entry entry = itel.next(); + + if (UtilTime.elapsed(entry.getValue(), 920)) + { + itel.remove(); + + int id = entry.getKey(); + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[] + { + id + }); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + Location loc = _blockLoc.get(id); + FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockType.get(id), (byte) 0); + falling.setDropItem(false); + + _current.add(falling); + + Player target = _targetBlock.get(id); + + UtilEnt.CreatureLook(entity, target); + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1.2F); + entity.getWorld().playEffect(falling.getLocation(), Effect.STEP_SOUND, falling.getBlockId()); + + Location l = falling.getLocation(); + l.setY(entity.getLocation().getY()); + + Location loc1 = target.getEyeLocation(); + + if (loc1.getY() - l.getY() > 1) + { + loc1.setY(l.getY() + 1); + } + + int dist = (int) Math.ceil(loc1.toVector().setY(0).distance(l.toVector().setY(0))); + + Vector vector = UtilAlg.calculateVelocity(l.toVector(), loc1.toVector(), dist / 13); + + falling.setVelocity(vector); + } + } + } + + if (_thrown >= 3 && !UtilPlayer.getNearby(getLocation(), 10, true).isEmpty()) + { + _thrown = 99; + } + } + + @Override + public boolean inProgress() + { + return _thrown < _toThrow || !_current.isEmpty(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemCaveIn.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemCaveIn.java new file mode 100644 index 00000000..5656844a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemCaveIn.java @@ -0,0 +1,336 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; +import net.minecraft.server.v1_8_R3.MathHelper; +import net.minecraft.server.v1_8_R3.MovingObjectPosition; +import net.minecraft.server.v1_8_R3.Vec3D; + +public class GolemCaveIn extends BossAbility +{ + private List _blocks = new ArrayList<>(); + private List _fallingBlocks = new ArrayList<>(); + private int _tick; + + public GolemCaveIn(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public Player getTarget() + { + if (getTarget(4) == null) + { + return getTarget(40); + } + + return null; + } + + @Override + public boolean hasFinished() + { + return _tick > 60 && _fallingBlocks.isEmpty(); + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, + nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + if (canDamage(victim)) + { + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null, + DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Cave In", + "Iron Wizard Cave In"); + } + + cur.remove(); + fallingIterator.remove(); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c)); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt( + nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + cur.remove(); + fallingIterator.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + } + + @SuppressWarnings("deprecation") + @Override + public void setFinished() + { + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + + for (Block block : _blocks) + { + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId()); + block.setType(Material.AIR); + } + } + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + if (_tick++ == 0) + { + Location l = getLocation(); + + List blocks = UtilShapes.getSphereBlocks(l, 3, 3, true); + + for (Location loc : blocks) + { + if (loc.getBlockY() >= l.getBlockY()) + { + Block b = loc.getBlock(); + + if (b.getType() == Material.AIR) + { + _blocks.add(b); + + loc.setY(l.getY() - 1); + + b.setType(loc.getBlock().getType()); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, loc.getBlock().getTypeId()); + } + } + } + } + + if (_tick % 5 == 0) + + { + for (Player player : UtilPlayer.getNearby(getLocation(), 2.5, true)) + { + player.teleport(player.getLocation().add(0, 4, 0)); + UtilAction.velocity(player, new Vector(UtilMath.r(10) - 5, 3, UtilMath.r(10) - 5).normalize()); + } + } + + if (_tick < 200) + + { + Location loc = getLocation(); + loc.setY(loc.getY() + 4); + + for (int i = 0; i < 30; i++) + { + loc.setY(loc.getY() + 1); + Block b = loc.getBlock(); + + if (UtilBlock.solid(b)) + { + break; + } + } + + if (!UtilBlock.solid(loc.getBlock())) + { + return; + } + + List players = UtilPlayer.getNearby(getLocation(), 50, true); + + for (int i = 0; i < players.size() * 2; i++) + { + int dist = UtilMath.r(10); + + if (dist < 3) + { + dist = 2; + } + else if (dist < 5) + { + dist = 5; + } + else + { + dist = 10; + } + + Location l = players.get(UtilMath.r(players.size())).getLocation().add(UtilMath.r(dist * 2) - dist, 0, + UtilMath.r(dist * 2) - dist); + l.setY(loc.getY()); + + Block b = l.getBlock(); + l.subtract(0, 1, 0); + + if (UtilBlock.solid(b)) + { + if (l.getBlock().getType() == Material.AIR) + { + if (UtilAlg.HasSight(l, getLocation().add(0, 4, 0))) + { + FallingBlock block = b.getWorld().spawnFallingBlock(b.getLocation().add(0.5, -1, 0.5), b.getTypeId(), + b.getData()); + + block.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, block.getBlockId()); + block.setDropItem(false); + + _fallingBlocks.add(block); + } + } + } + } + } + + } + + @Override + public boolean inProgress() + { + return true; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemDeadlyTremor.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemDeadlyTremor.java new file mode 100644 index 00000000..d9934e3c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemDeadlyTremor.java @@ -0,0 +1,89 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import org.bukkit.Effect; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; + +public class GolemDeadlyTremor extends BossAbility +{ + private static final long ATTACK_DURATION = 10000; + private long _start; + + public GolemDeadlyTremor(GolemCreature creature) + { + super(creature); + _start = System.currentTimeMillis(); + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean inProgress() + { + return true; + } + + @Override + public boolean hasFinished() + { + return UtilTime.elapsed(_start, ATTACK_DURATION); + } + + @Override + public void setFinished() + { + _start = System.currentTimeMillis() - ATTACK_DURATION; + } + + @Override + public void tick() + { + for (Player player : UtilPlayer.getInRadius(getLocation(), 30).keySet()) + { + player.playSound(player.getLocation(), Sound.MINECART_BASE, 0.2f, 0.2f); + + if (UtilEnt.isGrounded(player)) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, (1 + 2 * Math.random()) * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Deadly Tremor"); + + if (Recharge.Instance.use(player, "Deadly Tremor Hit", 400, false, false)) + { + UtilAction.velocity(player, new Vector(Math.random() - 0.5, Math.random() * 0.2, Math.random() - 0.5), + Math.random() * 1 + 1, false, 0, 0.1 + Math.random() * 0.2, 2, true); + } + } + + for (Block block : UtilBlock.getInRadius(player.getLocation(), 5).keySet()) + { + if (Math.random() < 0.98) + continue; + + if (!UtilBlock.solid(block)) + continue; + + if (!UtilBlock.airFoliage(block.getRelative(BlockFace.UP))) + continue; + + player.playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemEarthquake.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemEarthquake.java new file mode 100644 index 00000000..ae4563a0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemEarthquake.java @@ -0,0 +1,168 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; + +public class GolemEarthquake extends BossAbility +{ + private Location _center; + private float _range; + private int _tick; + private List _damaged = new ArrayList<>(); + private boolean _earthquake; + + public GolemEarthquake(GolemCreature creature) + { + super(creature); + _center = getLocation(); + } + + @Override + public boolean canMove() + { + return !UtilEnt.isGrounded(getEntity()) && _tick > 1; + } + + @Override + public Player getTarget() + { + return getTarget(7); + } + + @Override + public boolean hasFinished() + { + return _range > 19; + } + + @Override + public void setFinished() + { + } + + @Override + public void tick() + { + Entity entity = getEntity(); + + if (_tick == 0) + { + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0); + + entity.setVelocity(new Vector(0, 1, 0)); + } + else if (!_earthquake) + { + _earthquake = _tick > 10 && UtilEnt.isGrounded(entity); + } + + if (_earthquake) + { + _range += 0.7; + + for (float range = _range - 2; range <= _range; range++) + { + if (range <= 0) + { + continue; + } + + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + if ((x != 0) == (z != 0)) + { + continue; + } + + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0), + _center.clone().add(x * range, 0.1, z * range), (x != 0) ? 0 : (range / 2), 0.1F, + (z != 0) ? 0 : (range / 2), 0, (int) (range * 4), UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + } + + _center.getWorld().playSound(_center, Sound.DIG_STONE, 2, 0.8F); + + HashSet toDamage = new HashSet(); + + Location cornerA = _center.clone().add(-_range, -1, -_range); + Location cornerB = _center.clone().add(_range, 1, _range); + Location cornerA1 = _center.clone().add(-(_range - 1.5), -1, -(_range - 1.5)); + Location cornerB1 = _center.clone().add(_range - 1.5, 1, _range - 1.5); + + for (Player player : Bukkit.getOnlinePlayers()) + { + Location pLoc = player.getLocation(); + + if (_damaged.contains(player.getUniqueId())) + { + continue; + } + + if (!UtilAlg.inBoundingBox(pLoc, cornerA, cornerB)) + { + continue; + } + + if (UtilAlg.inBoundingBox(pLoc, cornerA1, cornerB1)) + { + continue; + } + + toDamage.add(player); + } + + for (Player player : toDamage) + { + _damaged.add(player.getUniqueId()); + + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) player, getEntity(), null, + DamageCause.CONTACT, 14 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Earthquake", + "Iron Wizard Earthquake"); + + getBoss().getEvent().getCondition().Factory().Slow("Earthquake", (LivingEntity) player, getEntity(), 3, 1, false, + false, false, false); + + // Velocity + UtilAction.velocity(player, UtilAlg.getTrajectory2d(getLocation().toVector(), player.getLocation().toVector()), + 1.8, true, 0, 0.5, 0.5, true); + + // Condition + getBoss().getEvent().getCondition().Factory().Falling("Earthquake", player, getEntity(), 10, false, true); + } + } + + _tick++; + } + + @Override + public boolean inProgress() + { + return !_earthquake; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemExplodingAura.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemExplodingAura.java new file mode 100644 index 00000000..ff9fe2c6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemExplodingAura.java @@ -0,0 +1,400 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; +import net.minecraft.server.v1_8_R3.DataWatcher; +import net.minecraft.server.v1_8_R3.MathHelper; +import net.minecraft.server.v1_8_R3.MovingObjectPosition; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; +import net.minecraft.server.v1_8_R3.Vec3D; + +public class GolemExplodingAura extends BossAbility +{ + private Map _blocks = new HashMap<>(); + private Map _blocksLoc = new HashMap<>(); + private List _fallingBlocks = new ArrayList<>(); + private Map _blockMaterial = new HashMap<>(); + private int _tick; + + public GolemExplodingAura(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean hasFinished() + { + return _tick > 20 * 30 && _blocks.isEmpty() && _fallingBlocks.isEmpty(); + } + + @Override + public void setFinished() + { + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + + int[] ids = new int[_blocks.size() * 2]; + + int i = 0; + + for (Entry id : _blocks.entrySet()) + { + ids[i] = id.getKey(); + ids[i + 1] = id.getValue(); + + i += 2; + } + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + } + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + if (_tick < 25 * 25 && getBoss().getHealth() > 30) + { + double angle = (2 * Math.PI) / UtilMath.random.nextDouble(); + double x = 1.7 * Math.cos(angle); + double z = 1.7 * Math.sin(angle); + + Location loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z); + + loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId()); + + for (Player player : UtilPlayer.getNearby(getLocation(), 3, true)) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.CONTACT, + 6 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Protection", "Iron Wizard Protection"); + UtilAction.velocity(player, UtilAlg.getTrajectory(getEntity(), player), 1, true, 0.3, 0, 0.3, false); + } + } + + if (_tick < 20 * 30) + { + int key = UtilEnt.getNewEntityId(); + int value = UtilEnt.getNewEntityId(); + + Location loc = null; + + for (int i = 0; i < 30; i++) + { + double angle = (2 * Math.PI) / UtilMath.random.nextDouble(); + double x = 1.7 * Math.cos(angle); + double z = 1.7 * Math.sin(angle); + + loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z); + boolean found = false; + + for (Location l : _blocksLoc.values()) + { + if (l.distance(loc) < 0.3) + { + found = true; + break; + } + } + + if (found) + { + loc = null; + } + else + { + break; + } + } + + if (loc != null) + { + _blocks.put(key, value); + _blocksLoc.put(key, loc); + _blockMaterial.put(key, UtilMath.random.nextBoolean() ? Material.DIRT : Material.STONE); + + Packet[] packets = new Packet[3]; + + PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving(); + + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0); + watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0); + + packet1.a = key; + packet1.b = EntityType.SILVERFISH.getTypeId(); + packet1.c = (int) Math.floor(loc.getX() * 32); + packet1.d = (int) Math.floor((loc.getY() - 0.125) * 32); + packet1.e = (int) Math.floor(loc.getZ() * 32); + packet1.l = watcher; + + packets[0] = packet1; + + PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) getEntity()).getHandle(), 70, + _blockMaterial.get(key).getId()); + + packet2.a = value; + + packet2.b = (int) Math.floor(loc.getX() * 32); + packet2.c = (int) Math.floor(loc.getY() * 32); + packet2.d = (int) Math.floor(loc.getZ() * 32); + + packets[1] = packet2; + + PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); + + packet3.b = value; + packet3.c = key; + + packets[2] = packet3; + + for (Player player : UtilPlayer.getNearby(getLocation(), 70)) + { + UtilPlayer.sendPacket(player, packets); + } + } + } + + if (_tick % 25 == 0) + { + for (int i = 0; i < 3; i++) + getLocation().getWorld().playSound(getLocation(), Sound.DIG_GRASS, 3, 2); + + for (int key : new ArrayList(_blocksLoc.keySet())) + { + + PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(new int[] + { + key, _blocks.remove(key) + }); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, destroyPacket); + } + + Location loc = _blocksLoc.remove(key); + + FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockMaterial.remove(key), (byte) 0); + + _fallingBlocks.add(falling); + + Vector vec = UtilAlg.getTrajectory(getLocation().add(0, 1, 0), loc); + + vec.setY(Math.max(0.05, vec.getY())); + + falling.setVelocity(vec); + + loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId()); + } + } + + _tick++; + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, + nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + { + continue; + } + + // Creative or Spec + if (ent instanceof Player) + { + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + { + continue; + } + } + + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + { + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null, + DamageCause.CONTACT, 6 * getBoss().getDifficulty(), true, true, false, "Blocky Iron Wizard Aura", + "Blocky Iron Wizard Aura"); + } + + fallingIterator.remove(); + cur.remove(); + + Vector vec = UtilAlg.getTrajectory(getEntity(), victim); + vec.setY(0).normalize(); + + double strength = 1; + + if (!(victim instanceof Player) || !((Player) victim).isBlocking()) + { + strength = 1.3; + } + + UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c)); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt( + nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + fallingIterator.remove(); + cur.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + } + + @Override + public boolean inProgress() + { + return false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemExplosiveBlock.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemExplosiveBlock.java new file mode 100644 index 00000000..fd76b19e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemExplosiveBlock.java @@ -0,0 +1,590 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; +import net.minecraft.server.v1_8_R3.DataWatcher; +import net.minecraft.server.v1_8_R3.EntityIronGolem; +import net.minecraft.server.v1_8_R3.MathHelper; +import net.minecraft.server.v1_8_R3.MovingObjectPosition; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; +import net.minecraft.server.v1_8_R3.Vec3D; + +public class GolemExplosiveBlock extends BossAbility +{ + private Map _blocksLocation = new HashMap<>(); + private Location _center; + private int _explosionsLeft; + private FallingBlock _fallingBlock; + private Map _fallingBlocks = new HashMap<>(); + private List _items = new ArrayList<>(); + private int _strength; + private Player _target; + private int _tick; + + public GolemExplosiveBlock(GolemCreature creature, int strength) + { + super(creature); + + _strength = strength; + _center = getLocation().add(0, 3, 0); + _target = getTarget(); + + if (_target != null) + { + UtilEnt.CreatureLook(getEntity(), _target); + } + } + + @Override + public boolean canMove() + { + return _fallingBlock != null; + } + + private int clamp(int value) + { + if (value < -127) + { + return -127; + } + + if (value > 127) + { + return 127; + } + + return value; + } + + @Override + public Player getTarget() + { + HashMap locs = new HashMap(); + + for (Player player : UtilServer.getPlayers()) + { + double dist = player.getLocation().distance(_center); + + if (dist < 30) + { + double score = (dist > 10 ? 30 - dist : 10); + + for (Player p : UtilServer.getPlayers()) + { + if (player.getLocation().distance(p.getLocation()) < 4) + { + score += 7; + } + } + + if (player.hasLineOfSight(getEntity())) + { + score += 10; + } + + locs.put(player, score); + } + } + + Player lowest = null; + + for (Entry entry : locs.entrySet()) + { + if (lowest == null || locs.get(lowest) > locs.get(entry.getKey())) + { + lowest = entry.getKey(); + } + } + + return lowest; + } + + @Override + public boolean hasFinished() + { + return _target == null || (_fallingBlock != null && !_fallingBlock.isValid() && _explosionsLeft == 0); + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + if (_tick >= 40 + (40 * _strength) && _tick <= 50 + (40 * _strength)) + { + event.SetCancelled("Iron Wizard charging bomb"); + } + + event.SetKnockback(false); + } + } + + public void onExplode(final Location loc) + { + for (int i = 0; i < _strength * 2; i++) + { + if (i == 0) + { + onSubExplode(loc); + } + else + { + _explosionsLeft++; + + Bukkit.getScheduler().scheduleSyncDelayedTask(UtilServer.getPlugin(), () -> + { + onSubExplode(loc); + _explosionsLeft--; + }, 2 * i); + } + } + } + + public void onSubExplode(Location loc) + { + for (int i = 0; i < 2; i++) + { + Location l = loc.clone().add(UtilMath.r(_strength * 4) - (_strength * 2), UtilMath.r(_strength * 2), + UtilMath.r(_strength * 4) - (_strength * 2)); + + UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, l, _strength * 3, 1, _strength * 3, 0, _strength * 4, + ViewDist.LONG, UtilServer.getPlayers()); + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_fallingBlock == null) + { + return; + } + + if (_fallingBlock.isDead() + || !_fallingBlock.isValid() + || _fallingBlock.getTicksLived() > 400 + || !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4, + _fallingBlock.getLocation().getBlockZ() >> 4)) + { + Block block = _fallingBlock.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + _fallingBlock.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, _fallingBlock.getBlockId()); + + // Expire + if (_fallingBlock.getTicksLived() > 400 + || !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4, + _fallingBlock.getLocation().getBlockZ() >> 4)) + { + _fallingBlock.remove(); + return; + } + + _fallingBlock.remove(); + return; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) _fallingBlock).getHandle(); + Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) _fallingBlock.getWorld()).getHandle().getEntities( + ((CraftEntity) _fallingBlock).getHandle(), + ((CraftEntity) _fallingBlock).getHandle().getBoundingBox().a(((CraftEntity) _fallingBlock).getHandle().motX, + ((CraftEntity) _fallingBlock).getHandle().motY, ((CraftEntity) _fallingBlock).getHandle().motZ).grow(2, + 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + { + continue; + } + + // Creative or Spec + if (ent instanceof Player) + { + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + { + continue; + } + } + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + onExplode(victim.getEyeLocation()); + + _fallingBlock.remove(); + } + else if (finalObjectPosition != null) + { + Block block = _fallingBlock.getWorld() + .getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c)); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + onExplode(block.getLocation().add(0.5, 0.5, 0.5)); + + _fallingBlock.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + _fallingBlock.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + + @Override + public void setFinished() + { + int[] ids = new int[_fallingBlocks.size() * 2]; + + int index = 0; + + for (Entry entry : _fallingBlocks.entrySet()) + { + ids[index] = entry.getKey(); + ids[index + 1] = entry.getValue(); + index += 2; + } + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + for (Item item : _items) + { + item.remove(); + } + + if (_fallingBlock != null) + { + _fallingBlock.remove(); + } + } + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + IronGolem entity = getEntity(); + + Iterator itel = _items.iterator(); + + while (itel.hasNext()) + { + Item item = itel.next(); + + Vector vec = item.getVelocity(); + Location loc = item.getLocation(); + + if (item.getTicksLived() > 100 || vec.getY() <= 0 || loc.distance(_center) > loc.add(vec).distance(_center) + || UtilEnt.isGrounded(item)) + { + itel.remove(); + } + } + + // This spawns a floating block + if (_tick >= 20 && _tick % 60 == 0 && _fallingBlocks.size() < _strength) + { + int id = UtilEnt.getNewEntityId(); + int id2 = UtilEnt.getNewEntityId(); + + _fallingBlocks.put(id, id2); + _blocksLocation.put(id, _center.toVector()); + + Packet[] packets = new Packet[3]; + + PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving(); + + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0); + watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0); + + packet1.a = id; + packet1.b = EntityType.SILVERFISH.getTypeId(); + packet1.c = (int) Math.floor(_center.getX() * 32); + packet1.d = (int) Math.floor((_center.getY() - 0.125) * 32); + packet1.e = (int) Math.floor(_center.getZ() * 32); + packet1.l = watcher; + + packets[0] = packet1; + + PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, + Material.DIRT.getId()); + + packet2.a = id2; + + packet2.b = (int) Math.floor(_center.getX() * 32); + packet2.c = (int) Math.floor(_center.getY() * 32); + packet2.d = (int) Math.floor(_center.getZ() * 32); + + packets[1] = packet2; + + PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); + + packet3.b = id2; + packet3.c = id; + + packets[2] = packet3; + + for (Player player : UtilServer.getPlayers()) + { + if (player.getLocation().distance(_center) < 80) + { + UtilPlayer.sendPacket(player, packets); + } + } + } + + // This spawns a item that flies above the golem's head and disappears + if (UtilMath.r(6) == 0 && _tick < 40 + (_strength * 40)) + { + double angle = ((2 * Math.PI) / 30) * UtilMath.r(30); + double x = 5 * Math.cos(angle); + double z = 5 * Math.sin(angle); + Location loc = _center.clone().add(x, -3, z); + + Material mat = null; + + switch (UtilMath.r(3)) + { + case 0: + mat = Material.DIRT; + break; + case 1: + mat = Material.STONE; + break; + case 2: + mat = Material.COBBLESTONE; + break; + default: + break; + } + + Item item = loc.getWorld().dropItem(loc, new ItemBuilder(mat).setTitle(System.currentTimeMillis() + "").build()); + + item.setPickupDelay(999999); + + Vector vec = UtilAlg.getTrajectory(_center, item.getLocation()); + + vec.normalize().multiply(5); + + item.setVelocity(vec); + + // TODO Fix velocity + + _items.add(item); + } + + // 10 being when items no longer fly in, 0 being when its shot. + int ticksTillFired = (60 + (40 * _strength)) - _tick; + + if (ticksTillFired > 20) + { + int strength = (int) Math.floor(_tick / 20D); + + int nine = 8 - strength; + + if (_tick % nine == 0) + { + _center.getWorld().playSound(_center, Sound.DIG_GRASS, strength + 1, 1F); + } + } + else if (ticksTillFired < 0) + { + if (_tick % 3 == 0) + { + _center.getWorld().playSound(_fallingBlock.getLocation(), Sound.WOOD_CLICK, _strength + 1, 0.4F); + } + } + + // The location the falling blocks need to stick by + Vector blockCenter = _center.toVector(); + + if (ticksTillFired >= 0 && ticksTillFired <= 20) + { + Vector vec = entity.getLocation().add(entity.getLocation().getDirection().setY(0).normalize().multiply(1.2)) + .add(0, 1, 0).toVector(); + + blockCenter = UtilAlg.getTrajectory(_center.toVector(), blockCenter); + vec.multiply(ticksTillFired / 10D); + + _center.getWorld().playSound(_center, Sound.DIG_SNOW, _strength + 1, 0); + } + else if (_fallingBlock != null) + { + blockCenter = _fallingBlock.getLocation().add(0, 0.5, 0).toVector(); + } + + // Move the fake floating blocks + for (Entry entry : _fallingBlocks.entrySet()) + { + int id = entry.getKey(); + Vector vec = _blocksLocation.get(id); + + int x = clamp((int) ((blockCenter.getX() - vec.getX()) * 32) + (UtilMath.r(8) - 4)); + int y = clamp((int) ((blockCenter.getY() - vec.getY()) * 32) + (UtilMath.r(8) - 4)); + int z = clamp((int) ((blockCenter.getZ() - vec.getZ()) * 32) + (UtilMath.r(8) - 4)); + + vec.add(new Vector(x, y, z)); + + PacketPlayOutEntity.PacketPlayOutRelEntityMove packet = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(); + + packet.a = id; + + packet.b = (byte) x; + packet.c = (byte) y; + packet.d = (byte) z; + + for (Player player : UtilServer.getPlayers()) + { + if (player.getLocation().distance(_center) < 70) + { + UtilPlayer.sendPacket(player, packet); + + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + vec.toLocation(_center.getWorld()), 0.7F, 0.7F, 0.7F, 0, 11, ViewDist.NORMAL, player); + } + } + } + + if (ticksTillFired == 0) + { + int id = _fallingBlocks.keySet().iterator().next(); + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[] + { + id, _fallingBlocks.get(id) + }); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + _fallingBlocks.remove(id); + + _fallingBlock = _center.getWorld().spawnFallingBlock(_blocksLocation.get(id).toLocation(_center.getWorld()), + Material.STONE, (byte) 0); + + Vector vec1 = _fallingBlock.getLocation().toVector(); + Vector vec2 = _target.getLocation().toVector(); + + Vector vec = UtilAlg.calculateVelocity(vec1, vec2, (int) (vec1.distanceSquared(vec2) / 4)); + + _fallingBlock.setVelocity(vec); + + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + } + + _tick++; + } + + @Override + public boolean inProgress() + { + return false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemIronHook.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemIronHook.java new file mode 100644 index 00000000..18c94e4c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemIronHook.java @@ -0,0 +1,163 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Sound; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; + +public class GolemIronHook extends BossAbility +{ + private static final Integer MAX_TARGETS = 3; + private boolean _shot, _complete; + + private List _hooks = new ArrayList<>(); + + public GolemIronHook(GolemCreature creature) + { + super(creature); + _shot = false; + _complete = false; + } + + private int getPosition(Player toAdd, List ordered, Map distances) + { + int position = ordered.size(); + int index = 0; + for (Player player : ordered) + { + if (distances.get(player) < distances.get(toAdd)) + { + position = index; + } + index++; + } + + return position; + } + + private void shoot() + { + IronGolem wizard = getBoss().getEntity(); + List selections = new LinkedList<>(); + List targeted = new ArrayList<>(); + + Map near = UtilPlayer.getInRadius(wizard.getLocation(), 40D); + + for (Player nearby : near.keySet()) + { + if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + + if (selections.isEmpty()) + { + selections.add(nearby); + } + else + { + selections.add(getPosition(nearby, selections, near), nearby); + } + } + + for (int i = 0; i < MAX_TARGETS; i++) + { + if (i < selections.size()) + { + targeted.add(selections.get(i)); + } + } + + if (targeted.isEmpty()) + { + _complete = true; + setFinished(); + return; + } + + for (Player target : targeted) + { + Item item = wizard.getWorld().dropItem(wizard.getEyeLocation().add(UtilAlg.getTrajectory(wizard, target)), ItemStackFactory.Instance.CreateStack(131)); + UtilAction.velocity(item, UtilAlg.getTrajectory(wizard, target).normalize(), + 2, false, 0, 0.2, 20, false); + + getBoss().getEvent().getProjectileManager().AddThrow(item, getBoss().getEntity(), new IronHook(getBoss().getEvent()), -1, true, true, true, true, + Sound.FIRE_IGNITE, 1.4f, 0.8f, ParticleType.CRIT, UpdateType.TICK, 1f); + + item.getWorld().playSound(item.getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.8f); + _hooks.add(item); + } + } + + @Override + public int getCooldown() + { + return 10; + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return _complete; + } + + @Override + public void setFinished() + { + for (Item hook : _hooks) + { + if (!hook.isDead() && hook.isValid()) + { + getBoss().getEvent().getProjectileManager().deleteThrown(hook); + hook.remove(); + } + } + + _hooks.clear(); + } + + @Override + public void tick() + { + if (_shot) + { + return; + } + shoot(); + _shot = true; + Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () -> + { + _complete = true; + setFinished(); + }, 2 * 20); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemMeleeAttack.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemMeleeAttack.java new file mode 100644 index 00000000..a045429d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemMeleeAttack.java @@ -0,0 +1,90 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.EntityIronGolem; + +public class GolemMeleeAttack extends BossAbility +{ + private boolean _attacked; + + public GolemMeleeAttack(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public int getCooldown() + { + return 20; + } + + @Override + public Player getTarget() + { + return getTarget(4); + } + + @Override + public boolean hasFinished() + { + return _attacked; + } + + @Override + public void setFinished() {} + + @Override + public void tick() + { + _attacked = true; + + for (Player target : UtilPlayer.getNearby(getLocation(), 4, true)) + { + if (target.getVelocity().length() > 0.5) + { + continue; + } + + UtilEnt.CreatureLook(getEntity(), target); + + getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK, + 10 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Melee Attack", "Iron Wizard Melee Attack"); + + Vector vec = getLocation().getDirection(); + vec.setY(0).normalize().setY(0.5).multiply(2.4); + + UtilAction.velocity(target, vec); + + getBoss().getEvent().getCondition().Factory().Falling("Iron Wizard Throw", target, getEntity(), 3, false, false); + + target.getWorld().playSound(target.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F); + + EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + } + } + + @Override + public boolean inProgress() + { + return _attacked; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemRumble.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemRumble.java new file mode 100644 index 00000000..d9cb7cc7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemRumble.java @@ -0,0 +1,238 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem; +import org.bukkit.entity.Damageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.EntityIronGolem; + +/** + * Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it. + * Copy this from Wizards + */ +public class GolemRumble extends BossAbility +{ + private Location _loc; + private int _ticks; + private int _travelled; + private Vector _vec; + private int _width = 1; + private Location _target; + + public GolemRumble(GolemCreature creature) + { + super(creature); + + Player target = getTarget(); + + if (target != null) + { + _target = target.getLocation(); + + UtilEnt.CreatureLook(getEntity(), _target); + } + } + + @Override + public boolean canMove() + { + return _ticks >= 20; + } + + @Override + public boolean hasFinished() + { + return _travelled > 35; + } + + @Override + public void setFinished() {} + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + if (_ticks++ < 14) + { + IronGolem entity = getEntity(); + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + + if (_ticks % 2 == 0) + { + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 2F); + } + } + else if (_ticks % 2 == 0) + { + int oldWidth = _width; + + if ((_width <= 3 || _ticks % 4 == 0) && _width <= 6) + { + _width++; + } + + Location newLoc; + boolean validBlock = false; + List current = new ArrayList<>(); + + if (_vec == null) + { + _vec = _target.subtract(getLocation()).toVector().setY(0).normalize(); + _loc = getLocation().subtract(0, 1, 0).getBlock().getLocation().add(0, 0.99, 0); + newLoc = _loc; + current.add(_loc.getBlock()); + + validBlock = true; + } + else + { // Move rumble + newLoc = _loc.clone().add(_vec); + + // Check if the rumble needs to go up or drop a block or two + for (int y : new int[] {0, 1, -1}) + { + for (int a = 1; a <= 2; a++) + { + Block b = newLoc.clone().add(_vec.clone().multiply(a)).getBlock().getRelative(0, y, 0); + + if (UtilBlock.solid(b) && !UtilBlock.solid(b.getRelative(0, 1, 0))) + { + validBlock = true; + newLoc.add(0, y, 0); + + break; + } + } + + if (validBlock) + { + break; + } + } + + for (int width = -_width; width <= _width; width++) + { + if (Math.abs(width) <= oldWidth) + { + Block b = _loc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock(); + + if (!current.contains(b)) + { + current.add(b); + } + } + + if (validBlock) + { + Block b = newLoc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock(); + + if (!current.contains(b)) + { + current.add(b); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId()); + } + } + } + } + + UtilEnt.CreatureLook(getEntity(), _loc); + + for (Entity entity : getEntity().getWorld().getEntities()) + { + if (entity instanceof Damageable && !UtilPlayer.isSpectator(entity) && entity != getEntity()) + { + Block b = entity.getLocation().getBlock(); + boolean canDamage = false; + + for (int y = -1; y <= 0; y++) + { + if (current.contains(b.getRelative(0, y, 0))) + { + canDamage = true; + break; + } + } + + if (!canDamage) + { + continue; + } + + if (canDamage(entity)) + { + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) entity, getEntity(), null, + DamageCause.CONTACT, 8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Rumble", + "Iron Wizard Rumble"); + } + + UtilAction.velocity(entity, _vec.clone(), 1.5, true, 0, 0.2, 1, true); + + if (entity instanceof Player) + { + getBoss().getEvent().getCondition().Factory().Slow("Rumble", (LivingEntity) entity, getEntity(), 3, 1, + false, false, false, false); + } + } + } + + if (_travelled++ > 35 || !validBlock) + { + _travelled = 100; + } + + _loc = newLoc; + } + } + + public Player getTarget() + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getLocation(), 30, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getLocation()); + + if (d > 2 && (target == null || dist > d)) + { + target = player; + dist = d; + } + } + + return target; + } + + @Override + public boolean inProgress() + { + return _ticks < 14; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemRupture.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemRupture.java new file mode 100644 index 00000000..2ecf4c46 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemRupture.java @@ -0,0 +1,367 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.EntityIronGolem; + +public class GolemRupture extends BossAbility +{ + private List> _ruptures = new ArrayList<>(); + private Map _ruptureTime = new HashMap<>(); + private List _targetted = new ArrayList<>(); + private int _rupturesLeft; + private int _tick; + private List _items = new ArrayList<>(); + private int _ticksFinished; + + public GolemRupture(GolemCreature creature) + { + super(creature); + + if (creature.getHealthPercent() > 0.75) + { + _rupturesLeft = 2; + } + else if (creature.getHealthPercent() > 0.5) + { + _rupturesLeft = 5; + } + else + { + _rupturesLeft = 10; + } + } + + @Override + public boolean canMove() + { + return false; + } + + @EventHandler + public void HopperPickup(InventoryPickupItemEvent event) + { + if (_items.contains(event.getItem())) + { + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void ItemDestroy(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_items.isEmpty()) + { + return; + } + + Iterator itemIterator = _items.iterator(); + + while (itemIterator.hasNext()) + { + Item item = itemIterator.next(); + + if (item.isDead() || !item.isValid()) + { + item.remove(); + itemIterator.remove(); + } + else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60) + { + item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId()); + item.remove(); + itemIterator.remove(); + } + } + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return _rupturesLeft <= 0 && _ruptures.isEmpty() && --_ticksFinished <= 0; + } + + @Override + public void setFinished() + { + for (Item item : _items) + { + item.remove(); + } + } + + @Override + public void tick() + { + Iterator> itel = _ruptures.iterator(); + + while (itel.hasNext()) + { + Pair pair = itel.next(); + + if (pair.getLeft().distance(pair.getRight()) > 0) + { + Vector vec = pair.getRight().toVector().subtract(pair.getLeft().toVector()); + + if (vec.length() > 1) + { + vec = vec.normalize(); + } + + pair.getLeft().add(vec); + } + + if (pair.getLeft().distance(pair.getRight()) < 0.1) + { + if (!_ruptureTime.containsKey(pair.getLeft())) + { + _ruptureTime.put(pair.getLeft(), System.currentTimeMillis()); + } + else if (UtilTime.elapsed(_ruptureTime.get(pair.getLeft()), 150)) + { + itel.remove(); + + explodeRupture(pair.getLeft()); + } + } + } + + if (_tick % 10 == 0 && _rupturesLeft > 0) + { + _rupturesLeft--; + + Location loc = getLocation().add(UtilMath.random.nextFloat() - 0.5, 0, UtilMath.random.nextFloat() - 0.5); + + loc.setY(loc.getBlockY()); + + for (int y = 0; y > -3; y--) + { + if (!UtilBlock.airFoliage(loc.getBlock().getRelative(0, y, 0))) + { + loc.setY(loc.getY() + y); + break; + } + } + + Player player = getTarget(); + + if (player != null) + { + _targetted.add(player.getName()); + + Location target = player.getLocation(); + target.setY(loc.getY()); + + _ruptures.add(Pair.create(loc, target)); + + UtilEnt.CreatureLook(getEntity(), player.getLocation()); + + EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + } + else + { + _rupturesLeft = 0; + } + } + + for (Pair pair : _ruptures) + { + pair.getLeft().getWorld().playSound(pair.getLeft(), Sound.DIG_GRAVEL, 2.5F, 0.9F); + + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0), + pair.getLeft().clone().add(0, 1.1, 0), 1F, 0, 1F, 0, 70, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + + _tick++; + } + + @Override + public Player getTarget() + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getLocation(), 30, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + if (_targetted.contains(player.getName())) + { + continue; + } + + double d = player.getLocation().distance(getLocation()); + + if (d < 7) + { + continue; + } + + boolean valid = true; + + for (Pair loc : _ruptures) + { + if (loc.getRight().distance(player.getLocation()) < 1.5) + { + valid = false; + break; + } + } + + if (!valid) + { + continue; + } + + if (target == null || dist > d) + { + target = player; + dist = d; + } + } + + return target; + } + + @SuppressWarnings("deprecation") + private void explodeRupture(Location loc) + { + loc.add(0, 1.1, 0); + loc.setX(loc.getBlockX() + 0.5); + loc.setZ(loc.getBlockZ() + 0.5); + + // Fling + HashMap targets = UtilEnt.getInRadius(loc, 3.5); + for (LivingEntity cur : targets.keySet()) + { + // Velocity + UtilAction.velocity(cur, + UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()), + 0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true); + + // Condition + getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true); + + // Damage Event + getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM, + 8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture"); + } + + List blocks = new ArrayList<>(); + + for (int x = -3; x <= 3; x++) + { + for (int z = -3; z <= 3; z++) + { + for (int y = 0; y <= 1; y++) + { + for (int i = 0; i < 2; i++) + { + if (Math.sqrt(x * x + z * z + y * y) <= 3) + { + blocks.add(loc.clone().add(x, y, z).getBlock()); + } + } + } + } + } + + Collections.shuffle(blocks); + + // Blocks + int done = 0; + Iterator itel = blocks.iterator(); + + while (done < 30 && itel.hasNext()) + { + Block block = itel.next(); + + Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize(); + + if (!UtilBlock.airFoliage(block)) + { + continue; + } + + // Add Directional + vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5))); + + // Add Up + vec.add(new Vector(0, 1.6, 0)); + + vec.normalize(); + + // Scale + vec.multiply(0.1 + 0.3 * Math.random() + 0.6); + + // Block! + Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT, 0)); + item.setVelocity(vec); + item.setPickupDelay(50000); + _items.add(item); + + // Effect + loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.STONE.getId()); + + done++; + } + + _ticksFinished = 20; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemSlam.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemSlam.java new file mode 100644 index 00000000..c4a5a01a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemSlam.java @@ -0,0 +1,271 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; + +public class GolemSlam extends BossAbility +{ + private List _items = new ArrayList<>(); + private int _ticksFinished; + private int _stage; + private Vector _target; + private int _ticksJumped; + + public GolemSlam(GolemCreature creature) + { + super(creature); + + Player target = getTarget(); + + if (target != null) + { + _target = UtilAlg.calculateVelocity(getLocation().toVector(), + target.getLocation().toVector().setY(getLocation().getY()), 2, getEntity()); + } + } + + @Override + public boolean canMove() + { + return !UtilEnt.isGrounded(getEntity()) && _stage == 1; + } + + @Override + public boolean hasFinished() + { + return _stage == 2 && --_ticksFinished <= 0; + } + + @Override + public void setFinished() + { + for (Item item : _items) + { + item.remove(); + } + } + + @Override + public void tick() + { + Entity entity = getEntity(); + + if (_stage == 0) + { + UtilEnt.CreatureLook(getEntity(), getLocation().add(_target)); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0); + + entity.setVelocity(_target); + _stage++; + } + else if (_stage == 1) + { + _ticksJumped++; + + if (_ticksJumped > 4 && getLocation().subtract(0, 0.2, 0).getBlock().getType() != Material.AIR) + { + explodeRupture(getLocation()); + + _stage = 2; + } + } + } + + @EventHandler + public void HopperPickup(InventoryPickupItemEvent event) + { + if (_items.contains(event.getItem())) + { + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void ItemDestroy(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_items.isEmpty()) + { + return; + } + + Iterator itemIterator = _items.iterator(); + + while (itemIterator.hasNext()) + { + Item item = itemIterator.next(); + + if (item.isDead() || !item.isValid()) + { + item.remove(); + itemIterator.remove(); + } + else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60) + { + item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId()); + item.remove(); + itemIterator.remove(); + } + } + } + + @Override + public boolean inProgress() + { + return true; + } + + @Override + public Player getTarget() + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getLocation(), 30, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getLocation()); + + if (d < 10) + { + continue; + } + + if (target == null || dist > d) + { + target = player; + dist = d; + } + } + + return target; + } + + @SuppressWarnings("deprecation") + private void explodeRupture(Location loc) + { + loc.add(0, 1.1, 0); + loc.setX(loc.getBlockX() + 0.5); + loc.setZ(loc.getBlockZ() + 0.5); + + // Fling + Map targets = UtilEnt.getInRadius(loc, 3.5); + for (LivingEntity cur : targets.keySet()) + { + if (cur.equals(getEntity())) + { + continue; + } + + // Velocity + UtilAction.velocity(cur, + UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()), + 0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true); + + // Condition + getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true); + + // Damage Event + getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM, + 8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture"); + } + + List blocks = new ArrayList(); + + for (int x = -3; x <= 3; x++) + { + for (int z = -3; z <= 3; z++) + { + for (int y = 0; y <= 1; y++) + { + for (int i = 0; i < 2; i++) + { + if (Math.sqrt(x * x + z * z + y * y) <= 3) + { + blocks.add(loc.clone().add(x, y, z).getBlock()); + } + } + } + } + } + + Collections.shuffle(blocks); + + // Blocks + int done = 0; + Iterator itel = blocks.iterator(); + + while (done < 30 && itel.hasNext()) + { + Block block = itel.next(); + + Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize(); + + if (!UtilBlock.airFoliage(block)) + continue; + + // Add Directional + vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5))); + + // Add Up + vec.add(new Vector(0, 1.6, 0)); + + vec.normalize(); + + // Scale + vec.multiply(0.1 + 0.3 * Math.random() + 0.6); + + // Block! + Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT, 0)); + item.setVelocity(vec); + item.setPickupDelay(50000); + _items.add(item); + + // Effect + loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.DIRT.getId()); + + done++; + } + + _ticksFinished = 20; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemSpike.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemSpike.java new file mode 100644 index 00000000..4f5dad10 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemSpike.java @@ -0,0 +1,104 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.bukkit.Sound; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; + +public class GolemSpike extends BossAbility +{ + private static final int SPIKE_HEIGHT = 2; + private static final long ATTACK_DURATION = 1000 + (500 * SPIKE_HEIGHT * 2); + private static final long SPIKE_REMAIN = 1000; + private long _start; + private List _spikes; + + public GolemSpike(GolemCreature creature) + { + super(creature); + _start = System.currentTimeMillis(); + _spikes = new ArrayList<>(); + } + + @Override + public int getCooldown() + { + return 15; + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public boolean inProgress() + { + return true; + } + + @Override + public boolean hasFinished() + { + return UtilTime.elapsed(_start, ATTACK_DURATION) && _spikes.isEmpty(); + } + + @Override + public void setFinished() + { + _start = System.currentTimeMillis() - ATTACK_DURATION; + for (GroundSpike spike : _spikes) + { + spike.finish(); + } + _spikes.clear(); + } + + @Override + public void tick() + { + if (_spikes.isEmpty()) + { + for (Player player : UtilPlayer.getInRadius(getLocation(), 20).keySet()) + { + if (UtilEnt.isGrounded(player)) + { + player.playSound(player.getLocation(), Sound.STEP_STONE, 0.2f, 0.2f); + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, 5 * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Stone Spike"); + player.teleport(player.getLocation().add(0, SPIKE_HEIGHT, 0)); + UtilAction.velocity(player, player.getLocation().toVector().normalize().add(new Vector(0, 0.02, 0)).normalize()); + _spikes.add(new GroundSpike(player.getLocation().getBlock(), player.getLocation().getBlock().getRelative(0, -1, 0).getType(), new Random().nextInt(SPIKE_HEIGHT) + 2, SPIKE_REMAIN)); + } + } + } + else + { + List toRemove = new ArrayList<>(); + for (GroundSpike spike : _spikes) + { + spike.tick(); + if (spike.isFinished()) + { + toRemove.add(spike); + } + } + for (GroundSpike remove : toRemove) + { + _spikes.remove(remove); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemWallExplode.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemWallExplode.java new file mode 100644 index 00000000..aaebec6d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GolemWallExplode.java @@ -0,0 +1,419 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_8_R3.AxisAlignedBB; +import net.minecraft.server.v1_8_R3.MathHelper; +import net.minecraft.server.v1_8_R3.MovingObjectPosition; +import net.minecraft.server.v1_8_R3.Vec3D; + +public class GolemWallExplode extends BossAbility +{ + private Map> _blockWalls = new HashMap<>(); + private List _dontTarget = new ArrayList<>(); + private List _fallingBlocks = new ArrayList<>(); + private int _maxTimes = UtilMath.r(2) + 1; + private int _tick; + private int _timesDone; + private Map _wallTimers = new HashMap<>(); + + public GolemWallExplode(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public int getCooldown() + { + return 20; + } + + private float getMod(int div) + { + return UtilMath.random.nextFloat() / div; + } + + @Override + public Player getTarget() + { + for (Player player : UtilPlayer.getNearby(getLocation(), 15, true)) + { + if (_dontTarget.contains(player.getName())) + { + continue; + } + + if (player.getLocation().distance(getLocation()) <= 4) + { + continue; + } + + return player; + } + + return null; + } + + @Override + public boolean hasFinished() + { + return _wallTimers.isEmpty() && _fallingBlocks.isEmpty() && _timesDone >= _maxTimes; + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, + nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + if (canDamage(victim)) + { + getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null, + DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Wall Explosion", + "Iron Wizard Wall Explosion"); + } + + cur.remove(); + fallingIterator.remove(); + + Vector vec = cur.getVelocity(); + + UtilAction.velocity(victim, vec, 1.5, true, 0, 0.2, 1, true); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c)); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt( + nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + cur.remove(); + fallingIterator.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + + for (List list : _blockWalls.values()) + { + for (Block b : list) + { + b.setType(Material.AIR); + } + } + } + + @SuppressWarnings("deprecation") + @Override + public void tick() + { + if (_tick++ % 30 == 0 && _timesDone < _maxTimes) + { + _dontTarget.clear(); + + _timesDone++; + + for (int i = 0; i < 10; i++) + { + Player target = getTarget(); + + if (target == null) + { + if (_dontTarget.isEmpty()) + { + _timesDone = _maxTimes; + } + } + else + { + _dontTarget.add(target.getName()); + + UtilEnt.CreatureLook(getEntity(), target); + + BlockFace face = UtilShapes.getFacing(getLocation().getYaw()); + + if (_wallTimers.containsKey(face)) + { + continue; + } + + ArrayList blocks = new ArrayList(); + + Location loc = getLocation().getBlock().getLocation().add(0.5, 0, 0.5); + + int mul = (face.getModX() != 0 && face.getModZ() != 0) ? 2 : 3; + + loc.add(face.getModX() * mul, 0, face.getModZ() * mul); + + Block b = loc.getBlock(); + + BlockFace sideFace = UtilShapes.getSideBlockFaces(face, true)[0]; + boolean invalid = false; + + for (int mult = -3; mult <= 3; mult++) + { + Block block = b; + + if (Math.abs(mult) < 3) + { + block = block.getRelative(face); + } + + block = block.getRelative(sideFace, mult); + + if (Math.abs(mult) == 3 && face.getModX() != 0 && face.getModZ() != 0) + { + block = block.getRelative(UtilShapes.getSideBlockFaces(face, false)[mult < 0 ? 0 : 1]); + } + + if (!UtilAlg.HasSight(getLocation(), block.getLocation())) + { + invalid = true; + break; + } + + Block under = block.getRelative(0, -1, 0); + + if (!UtilBlock.solid(under)) + { + continue; + } + + for (int y = 0; y <= 1; y++) + { + block = block.getRelative(0, y, 0); + + if (block.getType() != Material.AIR) + { + invalid = true; + break; + } + + blocks.add(block); + } + + if (invalid) + { + break; + } + } + + if (invalid) + { + continue; + } + + for (Block block : blocks) + { + block.setType(block.getWorld().getBlockAt(block.getX(), b.getY() - 1, block.getZ()).getType()); + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId()); + } + + _blockWalls.put(face, blocks); + _wallTimers.put(face, System.currentTimeMillis()); + break; + } + } + } + + Iterator>> itel = _blockWalls.entrySet().iterator(); + boolean doExplode = false; + + while (itel.hasNext()) + { + Entry> entry = itel.next(); + BlockFace face = entry.getKey(); + + if (UtilTime.elapsed(_wallTimers.get(face), 1000)) + { + doExplode = true; + itel.remove(); + _wallTimers.remove(face); + + for (Block b : entry.getValue()) + { + FallingBlock block = getEntity().getWorld().spawnFallingBlock(b.getLocation().add(0.5, 0, 0.5), b.getType(), + (byte) 0); + + block.setDropItem(false); + + int index = entry.getValue().indexOf(b); + + BlockFace f = index == 8 || index == 9 ? BlockFace.SELF + : UtilShapes.getSideBlockFaces(face, true)[index > 6 ? 0 : 1]; + + block.setVelocity(new Vector((face.getModX() * 0.6) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15), + (face.getModZ() * 0.6) + (f.getModZ() * (0.05 + getMod(10))))); + + _fallingBlocks.add(block); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId()); + b.setType(Material.AIR); + } + } + } + + if (doExplode) + { + onUpdate(new UpdateEvent(UpdateType.TICK)); + } + } + + @Override + public boolean inProgress() + { + return false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GroundSpike.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GroundSpike.java new file mode 100644 index 00000000..40d2989e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/GroundSpike.java @@ -0,0 +1,122 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import java.util.LinkedList; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; + +public class GroundSpike +{ + private Block _initial; + private Material _type; + private int _max, _height; + private long _lastTick, _remain; + private LinkedList _blocks; + private boolean _shrinking, _finished; + + public GroundSpike(Block first, Material type, int maxHeight, long remainDuration) + { + _initial = first; + _type = type; + _height = 0; + _max = maxHeight; + _remain = remainDuration; + _lastTick = System.currentTimeMillis(); + _blocks = new LinkedList<>(); + _shrinking = false; + _finished = false; + } + + @SuppressWarnings("deprecation") + private void raise() + { + if ((_height + 1) < _max) + { + _lastTick = System.currentTimeMillis(); + Block b = _initial.getRelative(0, _height, 0); + for (Player player : UtilServer.getPlayers()) + { + player.sendBlockChange(b.getLocation(), _type, (byte)0); + } + _blocks.add(b); + _height++; + } + else + { + if (UtilTime.elapsed(_lastTick, _remain)) + { + _shrinking = true; + lower(); + } + } + } + + @SuppressWarnings("deprecation") + private void lower() + { + _height = Math.min(_blocks.size() - 1, _height); + if ((_height - 1) >= 0) + { + _lastTick = System.currentTimeMillis(); + for (Player player : UtilServer.getPlayers()) + { + player.sendBlockChange(_blocks.get(_height).getLocation(), Material.AIR, (byte)0); + } + _blocks.remove(_height); + _height--; + } + else + { + finish(); + } + } + + public boolean isFinished() + { + if (!_blocks.isEmpty()) + { + return false; + } + + return _finished; + } + + @SuppressWarnings("deprecation") + public void finish() + { + _finished = true; + for (Block block : _blocks) + { + for (Player player : UtilServer.getPlayers()) + { + player.sendBlockChange(block.getLocation(), Material.AIR, (byte)0); + } + } + _blocks.clear(); + } + + public void tick() + { + if (isFinished()) + { + return; + } + if (!UtilTime.elapsed(_lastTick, 500)) + { + return; + } + + if (_shrinking) + { + lower(); + } + else + { + raise(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/IronHook.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/IronHook.java new file mode 100644 index 00000000..94785a42 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/ironwizard/abilities/IronHook.java @@ -0,0 +1,60 @@ +package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities; + +import org.bukkit.block.Block; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.projectile.IThrown; +import mineplex.core.projectile.ProjectileUser; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; + +public class IronHook implements IThrown +{ + private WorldEvent _host; + + public IronHook(WorldEvent event) + { + _host = event; + } + + @Override + public void Collide(LivingEntity target, Block block, ProjectileUser data) + { + data.getThrown().remove(); + + if (!(data.getThrower() instanceof IronGolem)) + return; + + IronGolem wizard = (IronGolem)data.getThrower(); + + if (target == null) + return; + + UtilAction.velocity(target, UtilAlg.getTrajectory(target.getLocation(), wizard.getLocation()), 5, false, 0, 0.7, 1.2, true); + + _host.getCondition().Factory().Falling("Iron Hook", target, wizard, 10, false, true); + + _host.getDamageManager().NewDamageEvent(target, wizard, null, DamageCause.CUSTOM, 5, false, true, false, wizard.getName(), "Iron Hook"); + } + + @Override + public void Idle(ProjectileUser data) + { + data.getThrown().remove(); + } + + @Override + public void Expire(ProjectileUser data) + { + data.getThrown().remove(); + } + + @Override + public void ChunkUnload(ProjectileUser data) + { + data.getThrown().remove(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/SkeletonBoss.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/SkeletonBoss.java new file mode 100644 index 00000000..dd004675 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/SkeletonBoss.java @@ -0,0 +1,65 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.boss.BossWorldEvent; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType; + +public class SkeletonBoss extends BossWorldEvent +{ + protected boolean canMove = false; + + public SkeletonBoss(WorldEventManager manager) + { + super("Skeleton King", manager.getBossArenaLocationFinder().getSkeletonKingCenter(), 50, manager.getBossArenaLocationFinder().getSkeletonKingPads().getLeft(), manager.getBossArenaLocationFinder().getSkeletonKingPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition()); + } + + @Override + protected void customStart() + { + Bukkit.broadcastMessage(F.main(getName(), "The evils of the world have manifested in the form of the " + getName() + "! Become the champion of Light and destroy him!")); + spawnSkeletonKing(getCenterLocation()); + Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () -> + { + canMove = true; + }, 20 * 3); + } + + public EventCreature spawnMinion(MinionType type, Location location) + { + EventCreature minionCreature = type.getNewInstance(this, location); + if (minionCreature != null) + { + registerCreature(minionCreature); + } + return minionCreature; + } + + private SkeletonCreature spawnSkeletonKing(Location location) + { + SkeletonCreature kingCreature = new SkeletonCreature(this, location); + registerCreature(kingCreature); + setBossCreature(kingCreature); + return kingCreature; + } + + @Override + public String getDeathMessage() + { + return F.main(getName(), "The demonic " + getName() + " has been slain!"); + } + + @Override + protected void customTick() {} + + @Override + public void customCleanup(boolean onDisable) {} + + @Override + protected void customStop() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/SkeletonCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/SkeletonCreature.java new file mode 100644 index 00000000..be6ae17e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/SkeletonCreature.java @@ -0,0 +1,482 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Skeleton.SkeletonType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonArcherShield; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonPassive; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonPulse; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonSmite; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonStrike; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonWraithSummon; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadWarriorCreature; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class SkeletonCreature extends EventCreature +{ + private List> _currentAbilities = new ArrayList<>(); + private SkeletonPassive _passive; + private int _lastAbility; + private Map, Long> _cooldowns = new HashMap<>(); + private LinkedList _wraithTriggers = new LinkedList<>(); + private List _movePoints = new ArrayList<>(); + private Location _movingTo; + private boolean _moving; + private long _lastMoved; + private long _lastUsedPassive; + public List Archers = new ArrayList<>(); + public List Warriors = new ArrayList<>(); + + public SkeletonCreature(SkeletonBoss boss, Location location) + { + super(boss, location, "Skeleton King", true, 2500, 30, true, Skeleton.class); + + spawnEntity(); + _passive = new SkeletonPassive(this); + _wraithTriggers.add(1500D); + _wraithTriggers.add(1000D); + _wraithTriggers.add(500D); + _wraithTriggers.add(100D); + getEntity().getWorld().setThunderDuration(10000000); + getEntity().getWorld().setThundering(true); + } + + @Override + protected void spawnCustom() + { + UtilEnt.vegetate(getEntity()); + getEntity().setSkeletonType(SkeletonType.WITHER); + getEntity().getEquipment().setItemInHand(new ItemStack(Material.RECORD_6)); //Meridian Scepter + getEntity().getEquipment().setItemInHandDropChance(0.f); + } + + @Override + public void dieCustom() + { + HandlerList.unregisterAll(_passive); + _passive = null; + endAbility(); + getEntity().getWorld().setThunderDuration(0); + getEntity().getWorld().setThundering(false); + } + + private void endAbility() + { + for (BossAbility ability : _currentAbilities) + { + ability.setFinished(); + HandlerList.unregisterAll(ability); + } + + _currentAbilities.clear(); + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_passive != null && ((SkeletonBoss)getEvent()).canMove) + { + if (UtilTime.elapsed(_lastUsedPassive, _passive.getCooldown() * 20) || _passive.isProgressing()) + { + _lastUsedPassive = System.currentTimeMillis(); + _passive.tick(); + } + } + + Iterator> itel = _currentAbilities.iterator(); + boolean canDoNew = _currentAbilities.size() < 3; + + while (itel.hasNext()) + { + BossAbility ability = itel.next(); + + if (ability.hasFinished()) + { + itel.remove(); + ability.setFinished(); + _lastAbility = 20;// _currentAbility.getCooldown(); + + HandlerList.unregisterAll(ability); + if (DEBUG_MODE) + { + System.out.print("Unregistered necromancer ability " + ability.getClass().getSimpleName()); + } + + _cooldowns.put(ability.getClass(), System.currentTimeMillis() + (ability.getCooldown() * 1000)); + } + else if (ability.inProgress()) + { + canDoNew = false; + _lastAbility = 20;// _currentAbility.getCooldown(); + } + } + + if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN))) + { + Map>, Integer> weight = new HashMap<>(); + Map dist = new HashMap<>(); + + for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true)) + { + if (player.hasLineOfSight(getEntity())) + { + dist.put(player, player.getLocation().distance(getEntity().getLocation())); + } + } + + if (!dist.isEmpty()) + { + {// Pulse & Strike + List players = getPlayers(dist, UtilMath.r(10) == 0 ? 25 : 20); + List near = getPlayers(dist, 5); + + if (!players.isEmpty()) + { + if (!near.isEmpty() && near.size() >= 4 && new Random().nextDouble() <= .45) + { + weight.put(SkeletonPulse.class, 999); + } + else + { + weight.put(SkeletonStrike.class, 6); + } + } + } + {// Smite + List players = getPlayers(dist, 15); + + if (!players.isEmpty()) + { + weight.put(SkeletonSmite.class, 6); + } + } + {//Archer Shield + List players = getPlayers(dist, 20); + double score = 0; + for (Player player : players) + { + score += (18 - dist.get(player)) / 2; + } + if (players.size() >= 4) + { + score += 17; + } + if (score > 0) + { + weight.put(SkeletonArcherShield.class, (int) Math.ceil(score)); + } + } + Double wraithUse = null; + for (Double test : _wraithTriggers) + { + if (wraithUse == null) + { + if (getHealth() <= test) + { + wraithUse = test; + break; + } + } + } + if (wraithUse != null) + {// Wraith Summon + _wraithTriggers.remove(wraithUse); + weight.clear(); + weight.put(SkeletonWraithSummon.class, 999); + } + } + + for (BossAbility ability : _currentAbilities) + { + weight.remove(ability.getClass()); + } + + for (Class c : _cooldowns.keySet()) + { + if (_cooldowns.get(c) > System.currentTimeMillis()) + { + weight.remove(c); + } + } + + if (_moving) + { + Iterator>> trying = weight.keySet().iterator(); + while (trying.hasNext()) + { + Class> abilityClass = trying.next(); + + try + { + BossAbility ability = abilityClass.newInstance(); + if (!ability.canMove()) + { + trying.remove(); + } + } + catch (Exception e) {} + } + } + + BossAbility ability = null; + + if (!weight.isEmpty()) + { + int i = 0; + + for (Integer entry : weight.values()) + { + i += entry; + } + + loop: for (int a = 0; a < 10; a++) + { + int luckyNumber = UtilMath.r(i); + + for (Entry>, Integer> entry : weight.entrySet()) + { + luckyNumber -= entry.getValue(); + + if (luckyNumber <= 0) + { + try + { + ability = entry.getKey().getConstructor(SkeletonCreature.class).newInstance(this); + + if (ability.getTarget() == null || ability.hasFinished()) + { + ability = null; + } + else + { + break loop; + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + break; + } + } + } + } + + if (ability != null && ability.getTarget() != null) + { + + Bukkit.getPluginManager().registerEvents(ability, UtilServer.getPlugin()); + + if (DEBUG_MODE) + { + System.out.print("Necromancer is using " + ability.getClass().getSimpleName()); + } + + _currentAbilities.add(ability); + } + + _lastAbility = 10; + } + + for (BossAbility ability : _currentAbilities) + { + try + { + ability.tick(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + boolean canMove = true; + for (BossAbility ability : _currentAbilities) + { + if (!ability.canMove()) + { + canMove = false; + } + } + if (!((SkeletonBoss)getEvent()).canMove) + { + return; + } + + if (_moving) + { + if (_movingTo == null) + { + _movingTo = selectWalkTarget(); + } + if (UtilMath.offset(getEntity().getLocation(), _movingTo) <= 1.3) + { + _lastMoved = System.currentTimeMillis(); + _movingTo = null; + _moving = false; + return; + } + UtilEnt.LookAt(getEntity(), _movingTo); + Vector walk = UtilAlg.getTrajectory(getEntity().getLocation(), _movingTo); + walk.multiply(walk.length()); + walk.multiply(.2); + getEntity().setVelocity(walk); + } + else + { + if (!UtilTime.elapsed(_lastMoved, 7000) || !canMove) + { + return; + } + _movingTo = selectWalkTarget(); + _moving = true; + } + } + + private Location selectWalkTarget() + { + if (_movePoints.isEmpty()) + { + Location base = getSpawnLocation().clone(); + base.setY(getEntity().getLocation().getY()); + generateWalkPoints(base); + } + Location selected = _movePoints.get(new Random().nextInt(_movePoints.size())); + _movePoints.remove(selected); + + return selected; + } + + private void generateWalkPoints(Location base) + { + _movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3))); + _movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3))); + _movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3))); + _movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3))); + } + + private List getPlayers(Map map, double maxDist) + { + return getPlayers(map, 0, maxDist); + } + + private List getPlayers(final Map map, double minDist, double maxDist) + { + List list = new ArrayList<>(); + + for (Player p : map.keySet()) + { + if (map.get(p) >= minDist && map.get(p) <= maxDist) + { + list.add(p); + } + } + + Collections.sort(list, (o1, o2) -> + { + return Double.compare(map.get(o2), map.get(o1)); + }); + + return list; + } + + @EventHandler + public void onSkeletonDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + event.SetKnockback(false); + } + } + + @EventHandler + public void noFallDamage(CustomDamageEvent event) + { + if (getEntity() == null) + { + return; + } + + if (event.GetDamageeEntity().getEntityId() != getEntity().getEntityId()) + { + return; + } + + DamageCause cause = event.GetCause(); + + if (cause == DamageCause.FALL) + { + event.SetCancelled("Boss Invulnerability"); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonArcherShield.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonArcherShield.java new file mode 100644 index 00000000..c4eadb5d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonArcherShield.java @@ -0,0 +1,187 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftSkeleton; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class SkeletonArcherShield extends BossAbility +{ + private static long ATTACK_DURATION = 10000; + private static long ARROW_DELAY = 100; + private static long ARROW_WARMUP = 2000; + private static double PULL_RANGE = 12; + private long _start; + private long _lastShoot; + private boolean _teleported; + + public SkeletonArcherShield(SkeletonCreature creature) + { + super(creature); + _start = System.currentTimeMillis(); + } + + @Override + public int getCooldown() + { + return 20; + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return UtilTime.elapsed(_start, ATTACK_DURATION); + } + + @Override + public void setFinished() + { + _start = System.currentTimeMillis() - ATTACK_DURATION; + for (UndeadArcherCreature creature : getBoss().Archers) + { + creature.getEntity().remove(); + } + } + + private void run(boolean initial) + { + for (int i = 0; i < getBoss().Archers.size(); i++) + { + Skeleton archer = getBoss().Archers.get(i).getEntity(); + UtilEnt.vegetate(archer); + ((CraftSkeleton)archer).setVegetated(false); + + double lead = i * ((2d * Math.PI)/getBoss().Archers.size()); + + double sizeMod = 2; + + //Orbit + double speed = 10d; + double oX = -Math.sin(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod; + double oY = 0; + double oZ = Math.cos(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod; + + if (initial) + { + archer.teleport(getEntity().getLocation().add(oX, oY, oZ)); + UtilEnt.vegetate(archer); + } + else + { + Location to = getEntity().getLocation().add(oX, oY, oZ); + UtilEnt.LookAt(archer, to); + UtilAction.velocity(archer, UtilAlg.getTrajectory(archer.getLocation(), to), 0.4, false, 0, 0.1, 1, true); + } + } + } + + private void shoot() + { + if (UtilTime.elapsed(_start, ARROW_WARMUP) && UtilTime.elapsed(_lastShoot, ARROW_DELAY)) + { + _lastShoot = System.currentTimeMillis(); + for (UndeadArcherCreature archer : getBoss().Archers) + { + Location spawn = archer.getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity().getEyeLocation(), archer.getEntity().getEyeLocation()).normalize()); + Vector vector = UtilAlg.getTrajectory(getEntity().getEyeLocation(), spawn); + Arrow arrow = archer.getEntity().getWorld().spawnArrow(spawn, vector, 0.6f, 12f); + arrow.setMetadata("SHIELD_SHOT", new FixedMetadataValue(UtilServer.getPlugin(), true)); + arrow.setMetadata("BARBED_ARROW", new FixedMetadataValue(UtilServer.getPlugin(), 10)); + arrow.setShooter(archer.getEntity()); + } + } + } + + @Override + public void tick() + { + if (!_teleported) + { + run(true); + _teleported = true; + for (Player near : UtilPlayer.getInRadius(getEntity().getLocation(), PULL_RANGE).keySet()) + { + Vector velocity = UtilAlg.getTrajectory(near, getEntity()); + UtilAction.velocity(near, velocity, 2, false, 0, 0, 1, true); + near.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 5 * 20, -2)); + for (int i = 0; i < 6; i++) + { + Vector random = new Vector(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2); + + Location origin = getEntity().getLocation().add(0, 1.3, 0); + origin.add(velocity.clone().multiply(10)); + origin.add(random); + + Vector vel = UtilAlg.getTrajectory(origin, getEntity().getLocation().add(0, 1.3, 0)); + vel.multiply(7); + + UtilParticle.PlayParticleToAll(ParticleType.MAGIC_CRIT, origin, (float)vel.getX(), (float)vel.getY(), (float)vel.getZ(), 1, 0, ViewDist.LONG); + } + } + } + else + { + run(false); + shoot(); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getBoss().getEntity())) + { + if (!hasFinished()) + { + event.SetCancelled("Wraiths Alive"); + } + } + } + + @EventHandler + public void onArrowHit(ProjectileHitEvent event) + { + if (event.getEntity().hasMetadata("SHIELD_SHOT")) + { + Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () -> + { + event.getEntity().remove(); + }, 20L); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonHellishFlood.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonHellishFlood.java new file mode 100644 index 00000000..794e75ad --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonHellishFlood.java @@ -0,0 +1,119 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import org.bukkit.Location; +import org.bukkit.entity.Skeleton; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType; + +public class SkeletonHellishFlood extends BossAbility +{ + private static final int WAVE_COUNT = 3; + private static final int WAVE_SIZE = 5; + private static final MinionType[] POSSIBLE_MINIONS = new MinionType[] {MinionType.WARRIOR, MinionType.ARCHER}; + private static final long WAVE_DELAY = 1000; + + private Map _waves = new HashMap<>(); + private long _lastSpawned; + private int _current; + private int _ticks; + + public SkeletonHellishFlood(SkeletonCreature creature) + { + super(creature); + + if (WAVE_COUNT > 0) + { + for (int i = 1; i <= WAVE_COUNT; i++) + { + createWave(i); + } + } + _lastSpawned = System.currentTimeMillis(); + _current = 1; + } + + private void createWave(int number) + { + int length = POSSIBLE_MINIONS.length; + if (length <= 0 || WAVE_SIZE <= 0) + { + return; + } + MinionType[] wave = new MinionType[WAVE_SIZE]; + for (int i = 0; i < WAVE_SIZE; i++) + { + wave[i] = POSSIBLE_MINIONS[new Random().nextInt(length)]; + } + _waves.put("Wave " + number, wave); + } + + @Override + public int getCooldown() + { + return 30; + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean inProgress() + { + return true; + } + + @Override + public boolean hasFinished() + { + return _waves.isEmpty() && _ticks > ((WAVE_DELAY / 1000) * 20 * (WAVE_COUNT - 1)); + } + + @Override + public void setFinished() + { + _waves.clear(); + _ticks = 60; + } + + @Override + public void tick() + { + _ticks++; + if (UtilTime.elapsed(_lastSpawned, WAVE_DELAY)) + { + if (_current <= WAVE_COUNT) + { + for (MinionType type : _waves.get("Wave " + _current)) + { + Location toSpawn = getLocation().clone(); + toSpawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6)); + + ((SkeletonBoss)getBoss().getEvent()).spawnMinion(type, toSpawn); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, toSpawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, toSpawn, null, 0, 2, ViewDist.MAX); + } + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + _waves.remove("Wave " + _current); + _current++; + _lastSpawned = System.currentTimeMillis(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonPassive.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonPassive.java new file mode 100644 index 00000000..20c542b2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonPassive.java @@ -0,0 +1,120 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadWarriorCreature; + +public class SkeletonPassive extends BossPassive +{ + private static final int MAX_ARCHERS = 10; + private static final int MAX_WARRIORS = 8; + private static final long SPAWN_RATE = 5000; + private List _queuedArchers = new ArrayList<>(); + private List _queuedWarriors = new ArrayList<>(); + private long _lastASpawned; + private long _lastWSpawned; + + public SkeletonPassive(SkeletonCreature creature) + { + super(creature); + } + + @Override + public int getCooldown() + { + return 20; + } + + @Override + public boolean isProgressing() + { + return !_queuedArchers.isEmpty() || !_queuedWarriors.isEmpty(); + } + + @Override + public void tick() + { + if (getBoss().Archers.size() < MAX_ARCHERS && _queuedArchers.isEmpty()) + { + for (int i = 0; i < (MAX_ARCHERS - getBoss().Archers.size()); i++) + { + Location spawn = getLocation().clone(); + spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6)); + _queuedArchers.add(spawn); + } + } + if (getBoss().Warriors.size() < MAX_WARRIORS && _queuedWarriors.isEmpty()) + { + for (int i = 0; i < (MAX_WARRIORS - getBoss().Warriors.size()); i++) + { + Location spawn = getLocation().clone(); + spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6)); + _queuedWarriors.add(spawn); + } + } + + for (Location animate : _queuedArchers) + { + UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0), + animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL); + } + for (Location animate : _queuedWarriors) + { + UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0), + animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL); + } + + if (!_queuedArchers.isEmpty() && UtilTime.elapsed(_lastASpawned, SPAWN_RATE)) + { + _lastASpawned = System.currentTimeMillis(); + Location spawn = _queuedArchers.remove(0); + getBoss().Archers.add((UndeadArcherCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.ARCHER, spawn)); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + } + if (!_queuedWarriors.isEmpty() && UtilTime.elapsed(_lastWSpawned, SPAWN_RATE)) + { + _lastWSpawned = System.currentTimeMillis(); + Location spawn = _queuedWarriors.remove(0); + getBoss().Warriors.add((UndeadWarriorCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WARRIOR, spawn)); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + } + } + + @EventHandler + public void onArcherDeath(EventCreatureDeathEvent event) + { + if (event.getCreature() instanceof UndeadArcherCreature) + { + getBoss().Archers.remove(event.getCreature()); + } + if (event.getCreature() instanceof UndeadWarriorCreature) + { + getBoss().Warriors.remove(event.getCreature()); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonPulse.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonPulse.java new file mode 100644 index 00000000..db28e149 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonPulse.java @@ -0,0 +1,108 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; + +public class SkeletonPulse extends BossAbility +{ + private static final long TOTAL_ATTACK_DURATION = 8000; + private static final long TOTAL_ATTACK_PROGRESS = 3000; + private long _start, _lastIncrement; + private int _radius; + private Location _center; + + public SkeletonPulse(SkeletonCreature creature) + { + super(creature); + _start = System.currentTimeMillis(); + _radius = 2; + _lastIncrement = System.currentTimeMillis(); + _center = creature.getEntity().getLocation(); + } + + private int getRadius() + { + return Math.min(8, _radius); + } + + @Override + public int getCooldown() + { + return 7; + } + + @Override + public boolean canMove() + { + return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS); + } + + @Override + public boolean inProgress() + { + return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS); + } + + @Override + public boolean hasFinished() + { + return UtilTime.elapsed(_start, TOTAL_ATTACK_DURATION); + } + + @Override + public void setFinished() + { + _start = System.currentTimeMillis() - TOTAL_ATTACK_DURATION; + } + + @Override + public void tick() + { + if (UtilTime.elapsed(_lastIncrement, 500)) + { + _lastIncrement = System.currentTimeMillis(); + _radius++; + } + + for (double token = 0; token <= (2 * Math.PI); token += .2) + { + double x = getRadius() * Math.cos(token); + double z = getRadius() * Math.sin(token); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, _center.clone().add(x, 1.5, z), null, 0, 1, ViewDist.MAX); + } + + for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), getRadius()).keySet()) + { + if (player.isDead() || !player.isValid() || !player.isOnline()) + { + continue; + } + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + if (!Recharge.Instance.use(player, "Pulse Knockback", 400, false, false, false)) + { + continue; + } + + player.playSound(player.getLocation(), Sound.AMBIENCE_THUNDER, 1f, 1f); + UtilAction.velocity(player, UtilAlg.getTrajectory2d(getEntity(), player), 2, false, 0.6, 0, 1.4, true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonSmite.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonSmite.java new file mode 100644 index 00000000..fc1a23de --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonSmite.java @@ -0,0 +1,104 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import java.math.BigDecimal; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; + +public class SkeletonSmite extends BossAbility +{ + private static final long TOTAL_ATTACK_DURATION = 8000; + private long _start; + private int _ticks; + private boolean _shot; + + public SkeletonSmite(SkeletonCreature creature) + { + super(creature); + _start = System.currentTimeMillis(); + _ticks = 0; + _shot = false; + } + + @Override + public int getCooldown() + { + return 15; + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean inProgress() + { + return true; + } + + @Override + public boolean hasFinished() + { + return UtilTime.elapsed(_start, TOTAL_ATTACK_DURATION) && _shot; + } + + @Override + public void setFinished() + { + _start = System.currentTimeMillis() - TOTAL_ATTACK_DURATION; + _shot = true; + } + + @Override + public void tick() + { + if (_shot) + return; + + if (_ticks < (6 * 20)) + { + _ticks++; + double maxHeight = Math.min(_ticks / 20, 6); + int radius = Math.max(6 - (new BigDecimal(_ticks).divide(new BigDecimal(20)).intValue()), 0); + + for (double y = 0; y < maxHeight; y += 0.5) + { + double cos = radius * Math.cos(y); + double sin = radius * Math.sin(y); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation().add(cos, y, sin), null, 0, 1, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation().add(sin, y, cos), null, 0, 1, ViewDist.MAX); + } + } + else + { + _shot = true; + for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), 15).keySet()) + { + if (player.isDead() || !player.isValid() || !player.isOnline()) + { + continue; + } + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + + player.getWorld().strikeLightningEffect(player.getLocation()); + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.LIGHTNING, 15 * getBoss().getDifficulty(), false, true, false, getEntity().getName(), "Lightning Strike"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonStrike.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonStrike.java new file mode 100644 index 00000000..b8588d0b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonStrike.java @@ -0,0 +1,167 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; + +public class SkeletonStrike extends BossAbility +{ + private static final double MAX_RANGE = 25; + private static final Integer MAX_TARGETS = 1; + private boolean _shot; + + public SkeletonStrike(SkeletonCreature creature) + { + super(creature); + _shot = false; + } + + private int getPosition(Player toAdd, LinkedList ordered) + { + int position = ordered.size(); + int index = 0; + for (Player player : ordered) + { + if (player.getHealth() < toAdd.getHealth()) + { + position = index; + return position; + } + index++; + } + + return position; + } + + private List getTargets() + { + Skeleton necromancer = getBoss().getEntity(); + LinkedList selections = new LinkedList<>(); + List targeted = new ArrayList<>(); + + Map near = UtilPlayer.getInRadius(necromancer.getLocation(), MAX_RANGE); + + for (Player nearby : near.keySet()) + { + if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + + if (selections.isEmpty()) + { + selections.addFirst(nearby); + } + else + { + selections.add(getPosition(nearby, selections), nearby); + } + } + + for (int i = 0; i < MAX_TARGETS; i++) + { + if (i < selections.size()) + { + targeted.add(selections.get(i)); + } + } + + return targeted; + } + + private void shootAt(Player target) + { + double curRange = 0; + boolean canHit = false; + + while (curRange <= MAX_RANGE) + { + Location newTarget = getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity(), target).multiply(curRange)); + + if (!UtilBlock.airFoliage(newTarget.getBlock())) + { + canHit = false; + break; + } + if (UtilMath.offset(newTarget, target.getLocation()) <= 0.9) + { + canHit = true; + break; + } + + curRange += 0.2; + + UtilParticle.PlayParticle(ParticleType.WITCH_MAGIC, newTarget, 0, 0, 0, 0, 1, + ViewDist.MAX, UtilServer.getPlayers()); + + canHit = true; + } + + if (canHit) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 12 * getBoss().getDifficulty(), true, true, false, getEntity().getName(), "Mystical Energy"); + } + } + + @Override + public int getCooldown() + { + return 15; + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return _shot; + } + + @Override + public void setFinished() + { + _shot = true; + } + + @Override + public void tick() + { + if (_shot) + return; + + _shot = true; + + for (Player target : getTargets()) + { + shootAt(target); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonWraithSummon.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonWraithSummon.java new file mode 100644 index 00000000..a8a8a33b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/abilities/SkeletonWraithSummon.java @@ -0,0 +1,231 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType; +import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.WraithCreature; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class SkeletonWraithSummon extends BossAbility +{ + private static final int WRAITH_AMOUNT = 4; + private static final double DISTANCE_FROM_KING = 4; + private static final double FINAL_SKELETON_HEALTH = 100; + private static final double FINAL_WRAITH_MULTIPLIER = 2; + private final int WRAITH_AMOUNT_THIS_USE; + + private Map _wraiths = new HashMap<>(); + private Location[] _spawns; + private int _ticks; + + public SkeletonWraithSummon(SkeletonCreature creature) + { + super(creature); + + _spawns = new Location[] + { + getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING), + getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING), + getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING * -1), + getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING * -1), + getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, DISTANCE_FROM_KING / 2), + getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, DISTANCE_FROM_KING / 2), + getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, (DISTANCE_FROM_KING / 2) * -1), + getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, (DISTANCE_FROM_KING / 2) * -1) + }; + + if (creature.getHealth() <= FINAL_SKELETON_HEALTH) + { + WRAITH_AMOUNT_THIS_USE = (int)(WRAITH_AMOUNT * FINAL_WRAITH_MULTIPLIER); + } + else + { + WRAITH_AMOUNT_THIS_USE = WRAITH_AMOUNT; + } + } + + private String getNumberString(Integer number) + { + String num = number.toString(); + char last = num.toCharArray()[num.length() - 1]; + + String formatted = number.toString(); + String ending = ""; + + if (last == '1' && !num.equals("1" + last)) + { + ending = "st"; + } + if (last == '2' && !num.equals("1" + last)) + { + ending = "nd"; + } + if (last == '3' && !num.equals("1" + last)) + { + ending = "rd"; + } + if (ending.equals("")) + { + ending = "th"; + } + + return formatted + ending; + } + + private void spawnWraith(Location loc, int number) + { + WraithCreature wraith = (WraithCreature)((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WRAITH, loc); + _wraiths.put(wraith, getNumberString(number)); + } + + @Override + public int getCooldown() + { + return 0; + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean inProgress() + { + return true; + } + + @Override + public boolean hasFinished() + { + return _wraiths.isEmpty() && _ticks > 40; + } + + @Override + public void setFinished() + { + for (WraithCreature wraith : _wraiths.keySet()) + { + wraith.remove(); + } + _wraiths.clear(); + _ticks = 41; + } + + @Override + public void tick() + { + if (_ticks == 0) + { + if (WRAITH_AMOUNT > 0) + { + for (int i = 0; i < WRAITH_AMOUNT_THIS_USE; i++) + { + int spawnIndex = i; + if (spawnIndex >= _spawns.length) + { + spawnIndex = spawnIndex % _spawns.length; + } + spawnWraith(_spawns[spawnIndex], i + 1); + } + + for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), 80).keySet()) + { + if (player.isDead() || !player.isValid() || !player.isOnline()) + { + continue; + } + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + + player.sendMessage(F.main(getBoss().getEvent().getName(), "You must slay all " + WRAITH_AMOUNT_THIS_USE + " wraiths before continuing to fight the " + getBoss().getEvent().getName() + "!")); + } + } + } + _ticks++; + if (!hasFinished()) + { + int ticks = 10; + int hticks = 40; + boolean up = getEntity().getTicksLived() % (hticks * 2) < hticks; + int tick = getEntity().getTicksLived() % ticks; + double htick = getEntity().getTicksLived() % hticks; + int splits = 4; + + Location loc = getEntity().getLocation().add(0, 2, 0); + + for (double d = tick * (Math.PI * 2 / splits) / ticks; d < Math.PI * 2; d += Math.PI * 2 / splits) + { + Vector v = new Vector(Math.sin(d), 0, Math.cos(d)); + v.normalize().multiply(Math.max(0.2, Math.sin((htick / hticks) * Math.PI) * 1.0)); + v.setY((htick / hticks) * -2); + if (up) v.setY(-2 + 2 * (htick / hticks)); + + Location lloc = loc.clone().add(v); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, lloc, null, 0f, 2, ViewDist.MAX); + } + } + } + + @EventHandler + public void onWraithDie(EventCreatureDeathEvent event) + { + if (event.getCreature() instanceof WraithCreature) + { + String number = _wraiths.remove(event.getCreature()); + if (number != null) + { + double remainPercent = new BigDecimal(_wraiths.size()).divide(new BigDecimal(WRAITH_AMOUNT_THIS_USE)).doubleValue(); + ChatColor remainColor = ChatColor.GREEN; + if (remainPercent < .66) + { + remainColor = ChatColor.YELLOW; + } + if (remainPercent < .33) + { + remainColor = ChatColor.RED; + } + Bukkit.broadcastMessage(F.main(getBoss().getEvent().getName(), "A wraith has been slain!" + " (" + remainColor + _wraiths.size() + "/" + WRAITH_AMOUNT_THIS_USE + C.cGray + ") wraiths remaining!")); + System.out.println(F.main(getBoss().getEvent().getName(), "The " + number + " wraith has been slain!")); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getBoss().getEntity())) + { + if (!hasFinished()) + { + event.SetCancelled("Wraiths Alive"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/MinionType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/MinionType.java new file mode 100644 index 00000000..8d2f779c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/MinionType.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion; + +import org.bukkit.Location; + +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; + +public enum MinionType +{ + WARRIOR(UndeadWarriorCreature.class), + ARCHER(UndeadArcherCreature.class), + WRAITH(WraithCreature.class); + + private Class> _code; + + private MinionType(Class> code) + { + _code = code; + } + + public EventCreature getNewInstance(WorldEvent event, Location spawn) + { + try + { + return _code.getConstructor(WorldEvent.class, Location.class).newInstance(event, spawn); + } + catch (Exception e) + { + e.printStackTrace(); + } + + return null; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/UndeadArcherCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/UndeadArcherCreature.java new file mode 100644 index 00000000..625b96c0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/UndeadArcherCreature.java @@ -0,0 +1,234 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class UndeadArcherCreature extends EventCreature +{ + private static final int BARBED_LEVEL = 1; + private static final int LIFETIME = -1; + + public UndeadArcherCreature(WorldEvent event, Location spawnLocation) + { + super(event, spawnLocation, "Undead Archer", true, 25, 30, true, Skeleton.class); + + spawnEntity(); + } + + @Override + protected void spawnCustom() + { + Skeleton entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setItemInHand(new ItemStack(Material.BOW)); + eq.setHelmet(new ItemStack(Material.CHAINMAIL_HELMET)); + eq.setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS)); + eq.setBoots(new ItemStack(Material.CHAINMAIL_BOOTS)); + eq.setItemInHandDropChance(0.f); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void dieCustom() + { + if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME)) + { + return; + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_HELMET)); + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_CHESTPLATE)); + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_LEGGINGS)); + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_BOOTS)); + } + + if (Math.random() > 0.90) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.BOW)); + } + + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.ARROW, UtilMath.r(12) + 1)); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void bowShoot(EntityShootBowEvent event) + { + if (BARBED_LEVEL == 0) + { + return; + } + + if (!(event.getProjectile() instanceof Arrow)) + { + return; + } + + if (event.getEntity().getEntityId() != getEntity().getEntityId()) + { + return; + } + + event.getProjectile().setMetadata("BARBED_ARROW", new FixedMetadataValue(UtilServer.getPlugin(), 2)); + } + + @EventHandler(priority = EventPriority.HIGH) + public void damage(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + if (event.GetCause() != DamageCause.PROJECTILE) + { + return; + } + + Projectile projectile = event.GetProjectile(); + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(true); + + if (projectile == null) + { + return; + } + + if (!projectile.hasMetadata("BARBED_ARROW")) + { + return; + } + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (!getEntity().equals(damager)) + { + return; + } + + // Level + if (BARBED_LEVEL == 0) + { + return; + } + + Player damageePlayer = event.GetDamageePlayer(); + + if (damageePlayer != null) + { + damageePlayer.setSprinting(false); + } + + // Damage + event.AddMod(damager.getName(), "Barbed Arrows", projectile.getMetadata("BARBED_ARROW").get(0).asDouble(), false); + + // Condition + getEvent().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true); + } + + @EventHandler + public void clean(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME)) + { + remove(); + return; + } + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/UndeadWarriorCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/UndeadWarriorCreature.java new file mode 100644 index 00000000..607a2c23 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/UndeadWarriorCreature.java @@ -0,0 +1,186 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class UndeadWarriorCreature extends EventCreature +{ + private static final int LIFETIME = -1; + + public UndeadWarriorCreature(WorldEvent event, Location spawnLocation) + { + super(event, spawnLocation, "Undead Warrior", true, 30, 30, true, Zombie.class); + spawnEntity(); + } + + @Override + protected void spawnCustom() + { + Zombie entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setHelmet(new ItemStack(Material.IRON_HELMET)); + eq.setChestplate(new ItemStack(Material.IRON_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.IRON_LEGGINGS)); + eq.setBoots(new ItemStack(Material.IRON_BOOTS)); + eq.setItemInHand(new ItemStack(Material.STONE_SWORD)); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + eq.setItemInHandDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void dieCustom() + { + if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME)) + { + return; + } + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_HELMET)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_CHESTPLATE)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_LEGGINGS)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_BOOTS)); + } + + @EventHandler + public void leap(UpdateEvent event) + { + if (getEntity() == null) + return; + + if (event.getType() != UpdateType.FAST) + return; + + if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME)) + { + remove(); + return; + } + + if (Math.random() < 0.9) + return; + + Zombie zombie = getEntity(); + + if (zombie.getTarget() == null) + return; + + double dist = UtilMath.offset(zombie.getTarget(), zombie); + + if (dist <= 3 || dist > 16) + return; + + + double power = 0.8 + (1.2 * ((dist-3)/13d)); + + //Leap + UtilAction.velocity(zombie, UtilAlg.getTrajectory(zombie, zombie.getTarget()), + power, false, 0, 0.2, 1, true); + + //Effect + zombie.getWorld().playSound(zombie.getLocation(), Sound.ZOMBIE_HURT, 1f, 2f); + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void attack(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(false); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damager)) + { + if (damagee instanceof Player) + { + ((Player)damagee).setFoodLevel(((Player)damagee).getFoodLevel() - 1); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/WraithCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/WraithCreature.java new file mode 100644 index 00000000..9a9cbcde --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/skeletonking/minion/WraithCreature.java @@ -0,0 +1,190 @@ +package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class WraithCreature extends EventCreature +{ + private static final int LIFETIME = -1; + + public WraithCreature(WorldEvent event, Location spawnLocation) + { + super(event, spawnLocation, "Wraith", true, 200, 30, true, Zombie.class); + spawnEntity(); + } + + @Override + protected void spawnCustom() + { + Zombie entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setHelmet(new ItemStack(Material.SKULL_ITEM, 1, (short)1)); + eq.setChestplate(new ItemBuilder(Material.LEATHER_CHESTPLATE).setColor(Color.BLACK).build()); + eq.setLeggings(new ItemBuilder(Material.LEATHER_LEGGINGS).setColor(Color.BLACK).build()); + eq.setBoots(new ItemBuilder(Material.LEATHER_BOOTS).setColor(Color.BLACK).build()); + eq.setItemInHand(new ItemStack(Material.IRON_SWORD)); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + eq.setItemInHandDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 999999, 0)); + entity.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 999999, 0)); + entity.addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, 999999, 0)); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 1)); + } + + @Override + public void dieCustom() + { + if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME)) + { + return; + } + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_HELMET)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_CHESTPLATE)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_LEGGINGS)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_BOOTS)); + } + + @EventHandler(priority = EventPriority.HIGH) + public void damage(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(false); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damager)) + { + event.AddMult(damager.getName(), "Mystical Darkness", 2, false); + } + } + + @EventHandler + public void blink(UpdateEvent event) + { + if (getEntity() == null) + return; + + if (event.getType() != UpdateType.FAST) + return; + + if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME)) + { + remove(); + return; + } + + if (Math.random() < 0.6) + return; + + Zombie zombie = getEntity(); + + if (zombie.getTarget() == null) + return; + + double dist = UtilMath.offset(zombie.getTarget(), zombie); + + if (dist <= 10 || dist > 25) + return; + + Location teleport = zombie.getTarget().getLocation().add(Math.random() + 1, 0, Math.random() + 1); + if (UtilMath.offset(getSpawnLocation(), teleport) > 30) + { + return; + } + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX); + zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 1f, 2f); + zombie.teleport(teleport); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX); + zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 1f, 2f); + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void protect(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + LivingEntity damagee = event.GetDamageeEntity(); + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + if (getEntity().equals(damagee)) + { + if (!(damager instanceof Player)) + { + event.SetCancelled("Allied Attacker"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/capturepoint/CapturePointEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/capturepoint/CapturePointEvent.java new file mode 100644 index 00000000..b064619d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/capturepoint/CapturePointEvent.java @@ -0,0 +1,170 @@ +package mineplex.game.clans.clans.worldevent.capturepoint; + +import java.util.Optional; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextTop; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; + +public class CapturePointEvent extends WorldEvent +{ + private static final long MAX_TICKS = UtilTime.convert(5, TimeUnit.MINUTES, TimeUnit.SECONDS) * 20; + private Player _capturing = null; + private Player _winner = null; + private Pair _resetData = null; + private PointBoundary _boundary = null; + private long _ticks = 0; + + public CapturePointEvent(WorldEventManager manager) + { + super("Capture Point", CapturePointLocation.getRandomLocation().toLocation(UtilWorld.getWorld("world")), 5, true, manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getDamage(), manager.getBlockRestore(), manager.getClans().getCondition()); + } + + @SuppressWarnings("deprecation") + @Override + protected void customStart() + { + Block set = getCenterLocation().getBlock().getRelative(BlockFace.DOWN); + _resetData = Pair.create(set.getType(), set.getData()); + set.setType(Material.BEACON); + double minX = (getCenterLocation().getBlockX() + 0.5) - 4.5; + double maxX = (getCenterLocation().getBlockX() + 0.5) + 4.5; + double minZ = (getCenterLocation().getBlockZ() + 0.5) - 4.5; + double maxZ = (getCenterLocation().getBlockZ() + 0.5) + 4.5; + double minY = getCenterLocation().getBlockY() + 1; + double maxY = getCenterLocation().getBlockY() + 4; + _boundary = new PointBoundary(minX, maxX, minZ, maxZ, minY, maxY); + } + + private boolean isEligible(Player player) + { + if (ClansManager.getInstance().hasTimer(player)) + { + if (Recharge.Instance.use(player, "PvP Timer Inform NoCapturePoint", 5000, false, false)) + { + UtilPlayer.message(player, F.main(getName(), "You cannot participate in the Capture Point whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + } + return false; + } + + return true; + } + + @Override + protected void customTick() + { + if (getState() != EventState.LIVE) + { + return; + } + if (_capturing == null) + { + Optional opt = Bukkit.getOnlinePlayers().stream() + .filter(_boundary::isInBoundary) + .filter(this::isEligible) + .findAny(); + if (opt.isPresent()) + { + _capturing = opt.get(); + Recharge.Instance.useForce(_capturing, "Capture Point Alert", 30000); + announceMessage(F.name(_capturing.getName()) + " is capturing the point!"); + } + } + else + { + if (!_boundary.isInBoundary(_capturing) || _capturing.isDead() || !_capturing.isOnline() || !_capturing.isValid()) + { + announceMessage(F.name(_capturing.getName()) + " has lost the point!"); + _capturing = null; + _ticks = 0; + } + else + { + _ticks++; + updateLastActive(); + if (_ticks >= MAX_TICKS) + { + _winner = _capturing; + UtilTextTop.display(C.cGoldB + "Capturing Point: " + C.cWhite + "100%", _capturing); + stop(); + return; + } + else if (Recharge.Instance.use(_capturing, "Capture Point Alert", 30000, false, false)) + { + announceMessage(F.name(_capturing.getName()) + " is still capturing the point!"); + } + double percentage = ((double)_ticks) / ((double)MAX_TICKS); + percentage *= 100; + UtilTextTop.display(C.cGoldB + "Capturing Point: " + C.cWhite + (int)Math.floor(percentage) + "%", _capturing); + } + } + } + + @SuppressWarnings("deprecation") + @Override + public void customCleanup(boolean onDisable) + { + Block reset = getCenterLocation().getBlock().getRelative(BlockFace.DOWN); + reset.setTypeIdAndData(_resetData.getLeft().getId(), _resetData.getRight(), false); + } + + @Override + protected void customStop() + { + if (_winner != null) + { + announceMessage(F.name(_winner.getName()) + " has captured the point!"); + for (int i = 0; i < 6; i++) + { + ClansManager.getInstance().getLootManager().dropCapturePoint(_winner.getLocation()); + } + } + else + { + announceMessage("Nobody was able to capture the point this time!"); + } + _winner = null; + _capturing = null; + _resetData = null; + } + + private class PointBoundary + { + private final double _minX, _maxX, _minZ, _maxZ, _minY, _maxY; + + public PointBoundary(double minX, double maxX, double minZ, double maxZ, double minY, double maxY) + { + _minX = minX; + _maxX = maxX; + _minZ = minZ; + _maxZ = maxZ; + _minY = minY; + _maxY = maxY; + } + + public boolean isInBoundary(Player player) + { + double x = player.getLocation().getX(); + double z = player.getLocation().getZ(); + double y = player.getLocation().getY(); + + return (x <= _maxX && x >= _minX) && (z <= _maxZ && z >= _minZ) && (y <= _maxY && y >= _minY); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/capturepoint/CapturePointLocation.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/capturepoint/CapturePointLocation.java new file mode 100644 index 00000000..7236e034 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/capturepoint/CapturePointLocation.java @@ -0,0 +1,35 @@ +package mineplex.game.clans.clans.worldevent.capturepoint; + +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Location; +import org.bukkit.World; + +public enum CapturePointLocation +{ + ONE(1075, 66, -456), + TWO(636, 65, 1102), + THREE(-1140, 57, -163), + FOUR(-636, 66, -948), + FIVE(-75, 51, -1004), + ; + + private final double _x, _y, _z; + + private CapturePointLocation(double x, double y, double z) + { + _x = x; + _y = y; + _z = z; + } + + public Location toLocation(World world) + { + return new Location(world, _x, _y, _z); + } + + public static CapturePointLocation getRandomLocation() + { + return CapturePointLocation.values()[ThreadLocalRandom.current().nextInt(CapturePointLocation.values().length)]; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/ClearCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/ClearCommand.java new file mode 100644 index 00000000..9a2c19d9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/ClearCommand.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.clans.worldevent.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.WorldEventManager; + +public class ClearCommand extends CommandBase +{ + public ClearCommand(WorldEventManager plugin) + { + super(plugin, WorldEventManager.Perm.STOP_EVENT_COMMAND, "clear"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.clearEvents(); + UtilPlayer.message(caller, F.main(Plugin.getName(), "All world events cleared!")); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/RandomCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/RandomCommand.java new file mode 100644 index 00000000..321a7932 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/RandomCommand.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.clans.worldevent.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.WorldEventType; + +/** + * Command for spawning a random world event in the world. + */ +public class RandomCommand extends CommandBase +{ + public RandomCommand(WorldEventManager plugin) + { + super(plugin, WorldEventManager.Perm.START_EVENT_COMMAND, "random", "rand"); + } + + @Override + public void Execute(Player caller, String[] args) + { + WorldEventType typeStarted = Plugin.randomEvent(); + if (typeStarted != null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Started " + F.name(typeStarted.getName()))); + } + else + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not start World Event")); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/StartCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/StartCommand.java new file mode 100644 index 00000000..e1cf0292 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/StartCommand.java @@ -0,0 +1,58 @@ +package mineplex.game.clans.clans.worldevent.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.WorldEventType; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; + +public class StartCommand extends CommandBase +{ + public StartCommand(WorldEventManager plugin) + { + super(plugin, WorldEventManager.Perm.START_EVENT_COMMAND, "start", "create"); + } + + @Override + public void Execute(Player caller, String[] args) + { + // start specific world event type + if (args != null && args.length == 1) + { + try + { + WorldEventType eventType = WorldEventType.valueOf(args[0]); + WorldEvent event = Plugin.startEventFromType(eventType); + + if (event == null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Error whilst starting the world event you chose.")); + } + else + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Started WorldEvent " + F.elem(args[0]) + "!")); + } + } + catch (IllegalArgumentException e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not find a WorldEvent with the name " + F.elem(args[0]) + "! Available types:")); + for (WorldEventType type : WorldEventType.values()) + { + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + type.toString()); + } + } + } + else + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "No World Event type specified. Available types:")); + for (WorldEventType type : WorldEventType.values()) + { + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + type.toString()); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java new file mode 100644 index 00000000..c14a07fe --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.clans.worldevent.command; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.MultiCommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.WorldEventManager; + +public class WorldEventCommand extends MultiCommandBase +{ + public WorldEventCommand(WorldEventManager plugin) + { + super(plugin, WorldEventManager.Perm.WORLD_EVENT_COMMAND, "worldevent", "we", "event"); + + AddCommand(new StartCommand(Plugin)); + AddCommand(new ClearCommand(Plugin)); + AddCommand(new RandomCommand(Plugin)); + } + + @Override + protected void Help(Player caller, String[] args) + { + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " start ", "Start a World Event", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " clear", "Clears all World Events", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/" + _aliasUsed + " random", "Starts a random World Event", ChatColor.DARK_RED)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/HillData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/HillData.java new file mode 100644 index 00000000..7ed32b8b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/HillData.java @@ -0,0 +1,55 @@ +package mineplex.game.clans.clans.worldevent.kinghill; + +import java.io.File; +import java.io.IOException; + +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.UtilSchematic; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; + +import org.bukkit.Location; + +public class HillData +{ + private Schematic _schematic; + private int _hillX; + private int _hillY; + private int _hillZ; + private int _lengthX; + private int _lengthY; + private int _lengthZ; + + public HillData(String fileName, int hillX, int hillY, int hillZ, int lengthX, int lengthY, int lengthZ) throws IOException + { + File file = new File("schematic" + File.separator + fileName); + System.out.println(file.getAbsolutePath()); + _schematic = UtilSchematic.loadSchematic(file); + _hillX = hillX; + _hillY = hillY; + _hillZ = hillZ; + _lengthX = lengthX; + _lengthY = lengthY; + _lengthZ = lengthZ; + } + + public Schematic getSchematic() + { + return _schematic; + } + + public boolean isOnHill(Location location, Location eventLocation) + { + return location.getWorld().equals(eventLocation.getWorld()) && UtilMath.offset(location, eventLocation.clone().add(0, 12, 0)) <= 7.5; + } + + public Location getHillCenter(Location eventLocation) + { + Location hill = eventLocation.clone(); + hill.add(_hillX, _hillY, _hillZ); + hill.add(_lengthX / 2.0, _lengthY / 2.0, _lengthZ / 2.0); + return hill; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/KingHill.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/KingHill.java new file mode 100644 index 00000000..5b6a64da --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/KingHill.java @@ -0,0 +1,196 @@ +package mineplex.game.clans.clans.worldevent.kinghill; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import mineplex.core.common.util.*; +import mineplex.minecraft.game.classcombat.Skill.SkillFactory; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.economy.GoldManager; +import mineplex.minecraft.game.core.boss.EventMap; +import mineplex.minecraft.game.core.boss.EventState; +import mineplex.minecraft.game.core.boss.WorldEvent; + +public class KingHill extends WorldEvent +{ + private static List LOADED_HILLS = new ArrayList(); + + private static int GOLD_PER_TICK = 4; + + private ClanInfo _clanOnHill; + + static + { + // TODO load hills from schematic folder with extra hill data from a + // config file? + try + { + LOADED_HILLS.add(new HillData("ClansKOTH.schematic", 28, 28, 28, 5, 5, 5)); + } + catch (IOException e) + { + e.printStackTrace(); + } + + } + + private ClansManager _clansManager; + private Map _scoreMap; + private HillData _hill; + private long _nextLootDrop; + private int _lootDropCount; + + private long _lastGoldDrop; + private long _lastOnHillMessage; + private long _goldDrops; + + public KingHill(WorldEventManager eventManager, Location centerLocation, SkillFactory skillFactory) + { + super(eventManager.getClans().getDisguiseManager(), eventManager.getClans().getProjectile(), eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), "King of the Hill", centerLocation); + _clansManager = eventManager.getClans(); + _scoreMap = new HashMap(); + _hill = LOADED_HILLS.get(0); + _nextLootDrop = System.currentTimeMillis() + getRandomRange(300000, 600000); + + } + + @Override + protected void customStart() + { + setMap(new EventMap(_hill.getSchematic(), getCenterLocation()), new Runnable() + { + @Override + public void run() + { + setState(EventState.LIVE); + } + }); + } + + @Override + protected void customCancel() + { + System.out.println("Custom Cancel - King Hill"); + } + + @Override + protected void customTick() + { + tickHill(); + + if (getState() == EventState.PREPARE) + { + System.out.println("Constructed " + getName() + " at " + UtilWorld.locToStrClean(getCenterLocation()) + "."); + announceStart(); + setState(EventState.LIVE); + } + + if (System.currentTimeMillis() > _nextLootDrop) + { + // Drop Loot! + _lootDropCount++; + _nextLootDrop = System.currentTimeMillis() + getRandomRange(300000, 600000); + + if (_lootDropCount >= 4) setState(EventState.COMPLETE); + } + } + + private void tickHill() + { + int clanCount = 0; + ClanInfo lastClan = null; + + for (Player player : UtilServer.getPlayers()) + { + if (_hill.isOnHill(player.getLocation(), getCenterLocation())) + { + ClanInfo playerClan = _clansManager.getClan(player); + if (playerClan != null && !playerClan.equals(lastClan)) + { + clanCount++; + lastClan = playerClan; + } + + updateLastActive(); + } + } + + if (clanCount == 1 && lastClan != null) + { + _clanOnHill = lastClan; + + CaptureData capData = _scoreMap.get(lastClan); + if (capData == null) + { + capData = new CaptureData(); + _scoreMap.put(lastClan, capData); + } + capData.TicksOnHill++; + + if (System.currentTimeMillis() - _lastGoldDrop > 20000) + { + _goldDrops = 1; + _lastGoldDrop = System.currentTimeMillis(); + } + + if (_goldDrops > 0 && _goldDrops < 200) + { + GoldManager.getInstance().dropGold(getCenterLocation().clone().add(0, 13, 0), GOLD_PER_TICK); + _goldDrops++; + } + else + { + _goldDrops = 0; + } + + if (System.currentTimeMillis() - _lastOnHillMessage > 60000) + { + Bukkit.broadcastMessage(F.main("Hill", F.elem(lastClan.getName()) + " own the hill (" + F.time(UtilTime.MakeStr(capData.TicksOnHill * 50)) + ")")); + _lastOnHillMessage = System.currentTimeMillis(); + } + } + else + { + _clanOnHill = null; + } + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + List list = new ArrayList(1); + + if (_clanOnHill != null && _scoreMap.containsKey(_clanOnHill)) + { + list.add(" " + _clanOnHill.getName() + " are on the Hill"); + } + + return list; + } + + private static class CaptureData + { + public int TicksOnHill; + } + + @Override + public void announceStart() + { + for(Player player : UtilServer.getPlayers()) { + if(_clansManager.getTutorial().inTutorial(player)) continue; + + UtilTextMiddle.display(C.cGreen + getName(), UtilWorld.locToStrClean(getCenterLocation()), 10, 100, 40, player); + player.sendMessage(F.main("Event", F.elem(getName()) + " has started at coordinates " + F.elem(UtilWorld.locToStrClean(getCenterLocation())))); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidAltar.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidAltar.java new file mode 100644 index 00000000..62ec129a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidAltar.java @@ -0,0 +1,199 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; + +public class RaidAltar +{ + private Block _altarBlock; + private RaidType _type; + private List _requiredItems; + + public RaidAltar(Block altarBlock, RaidType type, List requiredItems) + { + _altarBlock = altarBlock; + _type = type; + _requiredItems = requiredItems; + } + + @SuppressWarnings("deprecation") + private boolean has(Player player, Material type, String itemName, List lore, Byte data, Integer amount) + { + int count = 0; + for (ItemStack item : player.getInventory().getContents()) + { + boolean rejected = false; + if (item == null || item.getType() == Material.AIR) + { + continue; + } + if (type != null && item.getType() != type) + { + rejected = true; + } + if (itemName != null && (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !item.getItemMeta().getDisplayName().equals(itemName))) + { + rejected = true; + } + if (lore != null) + { + if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) + { + rejected = true; + } + else + { + List itemLore = item.getItemMeta().getLore(); + if (itemLore.size() != lore.size()) + { + rejected = true; + } + else + { + for (int i = 0; i < lore.size(); i++) + { + if (!itemLore.get(i).equals(lore.get(i))) + { + rejected = true; + } + } + } + } + } + if (data != null) + { + if (item.getData().getData() != data) + { + rejected = true; + } + } + + if (!rejected) + { + count += item.getAmount(); + } + } + + if (amount != null) + { + return count >= amount; + } + else + { + return count > 0; + } + } + + @SuppressWarnings("deprecation") + private void remove(Player player, Material type, String itemName, List lore, Byte data, int amount) + { + int removed = 0; + for (int i = 0; i < player.getInventory().getContents().length; i++) + { + ItemStack item = player.getInventory().getContents()[i]; + if (removed >= amount) + { + return; + } + boolean rejected = false; + if (item == null || item.getType() == Material.AIR) + { + continue; + } + if (type != null && item.getType() != type) + { + rejected = true; + } + if (itemName != null && (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() || !item.getItemMeta().getDisplayName().equals(itemName))) + { + rejected = true; + } + if (lore != null) + { + if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) + { + rejected = true; + } + else + { + List itemLore = item.getItemMeta().getLore(); + if (itemLore.size() != lore.size()) + { + rejected = true; + } + else + { + for (int index = 0; index < lore.size(); index++) + { + if (!itemLore.get(index).equals(lore.get(index))) + { + rejected = true; + } + } + } + } + } + if (data != null) + { + if (item.getData().getData() != data) + { + rejected = true; + } + } + + if (!rejected) + { + if (item.getAmount() > (amount - removed)) + { + removed += (amount - removed); + item.setAmount(item.getAmount() - removed); + } + else + { + removed += item.getAmount(); + player.getInventory().setItem(i, null); + } + } + } + + player.updateInventory(); + } + + @SuppressWarnings("deprecation") + public boolean handleInteract(Player player, Block block) + { + if (_altarBlock.equals(block)) + { + for (ItemStack required : _requiredItems) + { + String displayName = ((required.hasItemMeta() && required.getItemMeta().hasDisplayName()) ? required.getItemMeta().getDisplayName() : null); + List lore = ((required.hasItemMeta() && required.getItemMeta().hasLore()) ? required.getItemMeta().getLore() : null); + if (!has(player, required.getType(), displayName, lore, required.getData().getData(), required.getAmount())) + { + UtilPlayer.message(player, F.main(_type.getRaidName() + " Raid", "You do not have the required summoning items for this raid!")); + return true; + } + } + if (ClansManager.getInstance().getWorldEvent().getRaidManager().startRaid(player, _type)) + { + for (ItemStack required : _requiredItems) + { + String displayName = ((required.hasItemMeta() && required.getItemMeta().hasDisplayName()) ? required.getItemMeta().getDisplayName() : null); + List lore = ((required.hasItemMeta() && required.getItemMeta().hasLore()) ? required.getItemMeta().getLore() : null); + remove(player, required.getType(), displayName, lore, required.getData().getData(), required.getAmount()); + } + } + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidChallenge.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidChallenge.java new file mode 100644 index 00000000..6f30d874 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidChallenge.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; + +public abstract class RaidChallenge implements Listener +{ + private T _raid; + private String _name; + private boolean _completed; + + public RaidChallenge(T raid, String name) + { + _raid = raid; + _name = name; + _completed = false; + } + + public abstract void customStart(); + public abstract void customComplete(); + + public T getRaid() + { + return _raid; + } + + public String getName() + { + return _name; + } + + public boolean isComplete() + { + return _completed; + } + + public void start() + { + customStart(); + UtilServer.RegisterEvents(this); + UtilTextMiddle.display("", getName(), getRaid().getPlayers().toArray(new Player[getRaid().getPlayers().size()])); + } + + public void complete() + { + complete(true); + } + + public void complete(boolean allowCustom) + { + if (allowCustom) + { + customComplete(); + } + HandlerList.unregisterAll(this); + _completed = true; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidCreature.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidCreature.java new file mode 100644 index 00000000..7d18b0fd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidCreature.java @@ -0,0 +1,16 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; + +import mineplex.game.clans.clans.worldevent.api.EventCreature; + +public abstract class RaidCreature extends EventCreature +{ + public RaidCreature(RaidWorldEvent event, Location spawnLocation, String name, boolean useName, double health, double walkRange, boolean healthRegen, Class entityClass) + { + super(event, spawnLocation, name, useName, health, walkRange, healthRegen, entityClass); + } + + public abstract void handleDeath(Location location); +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java new file mode 100644 index 00000000..f51e2a18 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java @@ -0,0 +1,223 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.projectile.ProjectileManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.utils.UtilScheduler; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.raid.command.StartRaidCommand; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +public class RaidManager extends MiniPlugin +{ + public enum Perm implements Permission + { + START_RAID_COMMAND, + } + + private static final int MAX_PARTICIPANTS = 10; + + private Set _raids = new HashSet<>(); + private List _altars = new ArrayList<>(); + + public RaidManager(JavaPlugin plugin) + { + super("Raid Manager", plugin); + + addCommand(new StartRaidCommand(this)); + + { + List items = new ArrayList<>(); + items.add(new ItemStack(Material.BONE, 20)); + items.add(new ItemBuilder(Material.IRON_INGOT).setAmount(2).setTitle(C.cDRedB + "Old Silver Token").setLore(C.cRed + "This token pulses with an evil aura.").setGlow(true).build()); + _altars.add(new RaidAltar(new Location(Bukkit.getWorld("world"), 361, 57, -990).getBlock(), RaidType.CHARLES_WITHERTON, items)); + } + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.START_RAID_COMMAND, true, true); + } + + @Override + public void disable() + { + _raids.forEach(raid -> raid.stop(true)); + _raids.clear(); + } + + private boolean isIneligible(Player player) + { + if (ClansManager.getInstance().hasTimer(player)) + { + if (Recharge.Instance.use(player, "PvP Timer Inform NoRaid", 5000, false, false)) + { + UtilPlayer.message(player, F.main(getName(), "You cannot enter a Raid whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + } + return true; + } + + return false; + } + + public DisguiseManager getDisguiseManager() + { + return ClansManager.getInstance().getDisguiseManager(); + } + + public ProjectileManager getProjectileManager() + { + return ClansManager.getInstance().getProjectile(); + } + + public DamageManager getDamageManager() + { + return ClansManager.getInstance().getDamageManager(); + } + + public BlockRestore getBlockRestore() + { + return ClansManager.getInstance().getBlockRestore(); + } + + public ConditionManager getConditionManager() + { + return ClansManager.getInstance().getCondition(); + } + + public int getActiveRaids() + { + return _raids.size(); + } + + public boolean isInRaid(Location loc) + { + for (RaidWorldEvent event : _raids) + { + if (event.WorldData.World.equals(loc.getWorld())) + { + return true; + } + } + + return false; + } + + public boolean startRaid(Player player, RaidType type) + { + if (_raids.size() >= 5) + { + UtilPlayer.message(player, F.main(type.getRaidName() + " Raid", "There are currently too many ongoing raids to start a new one!")); + return false; + } + Set inside = UtilPlayer.getInRadius(player.getLocation(), 4).keySet(); + inside.removeIf(this::isIneligible); + if (inside.size() > MAX_PARTICIPANTS) + { + UtilPlayer.message(player, F.main(type.getRaidName() + " Raid", "You cannot start a raid with more than " + MAX_PARTICIPANTS + " participants!")); + return false; + } + inside.forEach(in -> UtilPlayer.message(in, F.main(type.getRaidName() + " Raid", "Summoning ancient power..."))); + createNewRaid(type, raid -> inside.forEach(in -> + { + raid.addPlayer(in); + in.getWorld().strikeLightningEffect(in.getLocation()); + })); + return true; + } + + public void createNewRaid(RaidType type, Consumer raidConsumer) + { + final WorldData data = new WorldData(type.getRaidName()); + BukkitTask task = UtilScheduler.runEvery(UpdateType.TICK, () -> + { + if (data.Loaded) + { + try + { + RaidWorldEvent event = type.getClazz().getConstructor(WorldData.class, RaidManager.class).newInstance(data, this); + raidConsumer.accept(event); + event.start(); + _raids.add(event); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) + { + UtilServer.runSyncLater(data::uninitialize, 120); + e.printStackTrace(); + } + while (data.LoadChecker == null) {} + data.LoadChecker.cancel(); + } + }); + data.LoadChecker = task; + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.TICK) + { + UtilServer.getPlayersCollection() + .stream() + .filter(player -> isInRaid(player.getLocation())) + .forEach(player -> ClansManager.getInstance().getItemMapManager().removeMap(player)); + return; + } + if (event.getType() != UpdateType.SEC) + { + return; + } + + _raids.removeIf(e -> e.getState() == EventState.STOPPED); + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + + for (RaidAltar altar : _altars) + { + if (altar.handleInteract(event.getPlayer(), event.getClickedBlock())) + { + event.setCancelled(true); + return; + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidType.java new file mode 100644 index 00000000..ab655304 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidType.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; + +public enum RaidType +{ + CHARLES_WITHERTON("Charles Witherton", WitherRaid.class); + + private String _raidName; + private Class _clazz; + + private RaidType(String raidName, Class clazz) + { + _raidName = raidName; + _clazz = clazz; + } + + public String getRaidName() + { + return _raidName; + } + + public Class getClazz() + { + return _clazz; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidWorldEvent.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidWorldEvent.java new file mode 100644 index 00000000..a43d05e1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidWorldEvent.java @@ -0,0 +1,319 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.world.ChunkUnloadEvent; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +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; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.game.clans.spawn.Spawn; + +public abstract class RaidWorldEvent extends WorldEvent +{ + private static int nextId = 0; + + protected RaidManager Manager; + protected WorldData WorldData; + + protected final int Id; + + private List _players = new ArrayList<>(); + + protected long _forceEnd = -1; + + private boolean _cleanup = false; + + public RaidWorldEvent(String name, WorldData data, RaidManager manager) + { + super(name, new Location(data.World, data.MinX + ((data.MaxX - data.MinX) / 2), data.MinY + ((data.MaxY - data.MinY) / 2), data.MinZ + ((data.MaxZ - data.MinZ) / 2)), UtilMath.getMax((data.MaxX - data.MinX) / 2, (data.MaxY - data.MinY) / 2, (data.MaxZ - data.MinZ) / 2), false, manager.getDisguiseManager(), manager.getProjectileManager(), manager.getDamageManager(), manager.getBlockRestore(), manager.getConditionManager()); + + Id = nextId++; + Manager = manager; + WorldData = data; + + loadNecessaryChunks(); + customLoad(); + } + + protected abstract void customLoad(); + + protected abstract void afterTeleportIn(); + + private void loadNecessaryChunks() + { + int minX = WorldData.MinX >> 4; + int minZ = WorldData.MinZ >> 4; + int maxX = WorldData.MaxX >> 4; + int maxZ = WorldData.MaxZ >> 4; + + for (int x = minX; x <= maxX; x++) + { + for (int z = minZ; z <= maxZ; z++) + { + WorldData.World.getChunkAt(x, z); + } + } + } + + public mineplex.game.clans.clans.worldevent.raid.WorldData getWorldData() + { + return WorldData; + } + + public List getPlayers() + { + List players = new ArrayList<>(); + players.addAll(_players); + return players; + } + + public int getId() + { + return Id; + } + + @Override + public void customStart() + { + _forceEnd = System.currentTimeMillis() + UtilTime.convert(90, TimeUnit.MINUTES, TimeUnit.MILLISECONDS); + int spawnIndex = 0; + List spawns = WorldData.SpawnLocs.get("Red"); + for (Player player : _players) + { + if (spawnIndex >= spawns.size()) + { + spawnIndex = 0; + } + player.teleport(spawns.get(spawnIndex)); + spawnIndex++; + } + afterTeleportIn(); + } + + @Override + public void customCleanup(boolean onDisable) + { + _cleanup = true; + _players.forEach(player -> player.teleport(Spawn.getNorthSpawn())); + _players.clear(); + getCreatures().forEach(creature -> + { + HandlerList.unregisterAll(creature); + creature.getEntity().remove(); + }); + getCreatures().clear(); + if (onDisable) + { + WorldData.uninitialize(); + } + else + { + UtilServer.runSyncLater(WorldData::uninitialize, 20 * 10); + } + } + + public void addPlayer(Player player) + { + _players.add(player); + } + + public void setForceEnd(long end) + { + _forceEnd = end; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + if (getState() != EventState.LIVE) + { + return; + } + if (_players.isEmpty()) + { + stop(); + } + else + { + updateLastActive(); + } + if (_forceEnd != -1 && System.currentTimeMillis() >= _forceEnd) + { + stop(); + } + } + + @EventHandler + public void onCreatureDeath(EventCreatureDeathEvent event) + { + if (!event.getCreature().getEvent().getName().equals(getName())) + { + return; + } + RaidWorldEvent worldEvent = (RaidWorldEvent) event.getCreature().getEvent(); + if (worldEvent.Id != Id) + { + return; + } + if (event.getCreature() instanceof RaidCreature) + { + ((RaidCreature)event.getCreature()).handleDeath(event.getCreature().getLastKnownLocation()); + } + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) + { + if (getState() == EventState.STOPPED || getState() == EventState.REMOVED || _cleanup) + { + return; + } + if (!event.getWorld().equals(WorldData.World)) + { + return; + } + event.setCancelled(true); + } + + @EventHandler + public void breakBlock(BlockBreakEvent event) + { + Block block = event.getBlock(); + Player player = event.getPlayer(); + + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + + if (!block.getWorld().equals(WorldData.World)) + { + return; + } + + event.setCancelled(true); + UtilPlayer.message(player, F.main(getName(), "You cannot build here!")); + } + + @EventHandler + public void placeBlock(BlockPlaceEvent event) + { + Block block = event.getBlock(); + Player player = event.getPlayer(); + + if (player.getGameMode() == GameMode.CREATIVE) + { + return; + } + + if (!block.getWorld().equals(WorldData.World)) + { + return; + } + + event.setCancelled(true); + UtilPlayer.message(player, F.main(getName(), "You cannot build here!")); + } + + @EventHandler(priority = EventPriority.LOW) + public void onQuit(PlayerQuitEvent event) + { + if (_cleanup) + { + return; + } + if (_players.remove(event.getPlayer())) + { + event.getPlayer().setHealth(0); + event.getPlayer().spigot().respawn(); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onDie(PlayerDeathEvent event) + { + if (_cleanup) + { + return; + } + _players.remove(event.getEntity()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onTeleport(PlayerTeleportEvent event) + { + if (_cleanup) + { + return; + } + if (!event.getTo().getWorld().equals(WorldData.World)) + { + _players.remove(event.getPlayer()); + } + } + + @EventHandler + public void onTpHome(ClansCommandExecutedEvent event) + { + if (!_players.contains(event.getPlayer())) + { + return; + } + if (event.getCommand().equalsIgnoreCase("tphome") || event.getCommand().equalsIgnoreCase("stuck")) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot teleport while in a raid!")); + return; + } + if (event.getCommand().equalsIgnoreCase("claim") || event.getCommand().equalsIgnoreCase("unclaim") || event.getCommand().equalsIgnoreCase("unclaimall") || event.getCommand().equalsIgnoreCase("homeset")) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot manage your clan's territory while in a raid!")); + return; + } + } + + @Override + public boolean equals(Object object) + { + if (!(object instanceof RaidWorldEvent)) + { + return false; + } + + return ((RaidWorldEvent)object).getId() == getId(); + } + + @Override + public int hashCode() + { + return Integer.hashCode(getId()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/WorldData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/WorldData.java new file mode 100644 index 00000000..45913ae9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/WorldData.java @@ -0,0 +1,498 @@ +package mineplex.game.clans.clans.worldevent.raid; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Difficulty; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.scheduler.BukkitTask; + +import mineplex.core.common.timing.TimingManager; +import mineplex.core.common.util.FileUtil; +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.WorldUtil; +import mineplex.core.common.util.ZipUtil; +import mineplex.core.common.util.worldgen.WorldGenCleanRoom; +import mineplex.game.clans.spawn.Spawn; + +public class WorldData +{ + public int Id = -1; + + public String RaidName; + + public boolean Loaded = false; + + protected BukkitTask LoadChecker = null; + + public String File = null; + public String Folder = null; + + public World World; + public int MinX = 0; + public int MinZ = 0; + public int MaxX = 0; + public int MaxZ = 0; + + public int MinY = -1; + public int MaxY = 256; + + public Map> SpawnLocs = new LinkedHashMap<>(); + private Map> DataLocs = new LinkedHashMap<>(); + private Map> CustomLocs = new LinkedHashMap<>(); + private final Map _dataEntries = new LinkedHashMap<>(); + + public WorldData(String raidName) + { + RaidName = raidName; + initialize(); + + Id = getNewId(); + } + + private List loadFiles() + { + TimingManager.start("RaidManager LoadFiles"); + + File folder = new File(".." + java.io.File.separatorChar + ".." + java.io.File.separatorChar + "update" + java.io.File.separatorChar + + "maps" + java.io.File.separatorChar + "Clans" + java.io.File.separatorChar + "Raids" + java.io.File.separatorChar + RaidName); + System.out.println(folder.getAbsolutePath() + " -=-=-=-=-="); + if (!folder.exists()) + { + folder.mkdirs(); + } + + List maps = new ArrayList<>(); + + System.out.println("Searching Maps in: " + folder); + + if (folder.listFiles() != null) + { + for (File file : folder.listFiles()) + { + if (!file.isFile()) + { + System.out.println(file.getName() + " is not a file!"); + continue; + } + + String name = file.getName(); + + if (name.length() < 5) + { + continue; + } + + name = name.substring(name.length() - 4, name.length()); + + if (!name.equals(".zip")) + { + System.out.println(file.getName() + " is not a zip."); + continue; + } + + maps.add(file.getName().substring(0, file.getName().length() - 4)); + } + } + + for (String map : maps) + { + System.out.println("Found Map: " + map); + } + + TimingManager.stop("RaidManager LoadFiles"); + + return maps; + } + + public void initialize() + { + getFile(); + + UtilServer.runAsync(() -> + { + WorldData.this.unzipWorld(); + UtilServer.runSync(() -> + { + TimingManager.start("WorldData loading world."); + + WorldCreator creator = new WorldCreator(getFolder()); + creator.generator(new WorldGenCleanRoom()); + World = WorldUtil.LoadWorld(creator); + + TimingManager.stop("WorldData loading world."); + + World.setDifficulty(Difficulty.HARD); + World.setGameRuleValue("showDeathMessages", "false"); + ((CraftWorld)World).getHandle().allowAnimals = false; + ((CraftWorld)World).getHandle().allowMonsters = false; + + TimingManager.start("WorldData loading WorldConfig."); + //Load World Data + WorldData.this.loadWorldConfig(); + TimingManager.stop("WorldData loading WorldConfig."); + }); + }); + } + + protected String getFile() + { + if (File == null) + { + int map; + try + { + map = UtilMath.r(loadFiles().size()); + } + catch (IllegalArgumentException e) + { + System.out.println("No maps found!"); + return null; + } + File = loadFiles().get(map); + } + + return File; + } + + public String getFolder() + { + if (Folder == null) + { + Folder = RaidName + Id + "_" + getFile(); + } + return Folder; + } + + protected void unzipWorld() + { + TimingManager.start("UnzipWorld creating folders"); + String folder = getFolder(); + new File(folder).mkdir(); + new File(folder + java.io.File.separator + "region").mkdir(); + new File(folder + java.io.File.separator + "data").mkdir(); + TimingManager.stop("UnzipWorld creating folders"); + + TimingManager.start("UnzipWorld UnzipToDirectory"); + ZipUtil.UnzipToDirectory("../../update/maps/Clans/Raids/" + RaidName + "/" + getFile() + ".zip", folder); + TimingManager.stop("UnzipWorld UnzipToDirectory"); + } + + public void loadWorldConfig() + { + //Load Track Data + String line = null; + + try + { + FileInputStream fstream = new FileInputStream(getFolder() + java.io.File.separator + "WorldConfig.dat"); + DataInputStream in = new DataInputStream(fstream); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + + List currentTeam = null; + List currentData = null; + + int currentDirection = 0; + + while ((line = br.readLine()) != null) + { + String[] tokens = line.split(":"); + + if (tokens.length < 2) + continue; + + if (tokens[0].length() == 0) + continue; + + //Spawn Locations + if (tokens[0].equalsIgnoreCase("TEAM_NAME")) + { + SpawnLocs.put(tokens[1], new ArrayList<>()); + currentTeam = SpawnLocs.get(tokens[1]); + currentDirection = 0; + } + else if (tokens[0].equalsIgnoreCase("TEAM_DIRECTION")) + { + currentDirection = Integer.parseInt(tokens[1]); + } + else if (tokens[0].equalsIgnoreCase("TEAM_SPAWNS")) + { + for (int i=1; i < tokens.length; i++) + { + Location loc = strToLoc(tokens[i]); + if (loc == null) continue; + + loc.setYaw(currentDirection); + + currentTeam.add(loc); + } + } + + //Data Locations + else if (tokens[0].equalsIgnoreCase("DATA_NAME")) + { + DataLocs.put(tokens[1], new ArrayList<>()); + currentData = DataLocs.get(tokens[1]); + } + else if (tokens[0].equalsIgnoreCase("DATA_LOCS")) + { + for (int i=1; i < tokens.length; i++) + { + Location loc = strToLoc(tokens[i]); + if (loc == null) continue; + + currentData.add(loc); + } + } + + //Custom Locations + else if (tokens[0].equalsIgnoreCase("CUSTOM_NAME")) + { + CustomLocs.put(tokens[1], new ArrayList<>()); + currentData = CustomLocs.get(tokens[1]); + } + else if (tokens[0].equalsIgnoreCase("CUSTOM_LOCS")) + { + for (int i=1; i < tokens.length; i++) + { + Location loc = strToLoc(tokens[i]); + if (loc == null) continue; + + currentData.add(loc); + } + } + + //Map Bounds + else if (tokens[0].equalsIgnoreCase("MIN_X")) + { + try + { + MinX = Integer.parseInt(tokens[1]); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MinX [" + tokens[1] + "]"); + } + + } + else if (tokens[0].equalsIgnoreCase("MAX_X")) + { + try + { + MaxX = Integer.parseInt(tokens[1]); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MaxX [" + tokens[1] + "]"); + } + } + else if (tokens[0].equalsIgnoreCase("MIN_Z")) + { + try + { + MinZ = Integer.parseInt(tokens[1]); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MinZ [" + tokens[1] + "]"); + } + } + else if (tokens[0].equalsIgnoreCase("MAX_Z")) + { + try + { + MaxZ = Integer.parseInt(tokens[1]); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MaxZ [" + tokens[1] + "]"); + } + } + else if (tokens[0].equalsIgnoreCase("MIN_Y")) + { + try + { + MinY = Integer.parseInt(tokens[1]); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MinY [" + tokens[1] + "]"); + } + } + else if (tokens[0].equalsIgnoreCase("MAX_Y")) + { + try + { + MaxY = Integer.parseInt(tokens[1]); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MaxY [" + tokens[1] + "]"); + } + } + else + { + _dataEntries.put(tokens[0], tokens[1]); + } + } + + in.close(); + + Loaded = true; + } + catch (Exception e) + { + e.printStackTrace(); + System.err.println("Line: " + line); + } + } + + protected Location strToLoc(String loc) + { + String[] coords = loc.split(","); + + try + { + return new Location(World, Integer.valueOf(coords[0]) +0.5, Integer.valueOf(coords[1]), Integer.valueOf(coords[2]) + 0.5); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid Location String [" + loc + "]"); + } + + return null; + } + + public void uninitialize() + { + if (World == null) + { + return; + } + + World.getPlayers().forEach(player -> player.teleport(Spawn.getNorthSpawn())); + + //Wipe World + MapUtil.UnloadWorld(UtilServer.getPlugin(), World); + MapUtil.ClearWorldReferences(World.getName()); + FileUtil.DeleteFolder(new File(World.getName())); + + World = null; + } + + public int getNewId() + { + File file = new File(RaidName + "RaidId.dat"); + + int id = 0; + + //Write If Blank + if (!file.exists()) + { + try ( + FileWriter fstream = new FileWriter(file); + BufferedWriter out = new BufferedWriter(fstream); + ) + { + out.write("0"); + } + catch (Exception e) + { + System.out.println("Error: Raid World GetId Write Exception"); + } + } + else + { + try ( + FileInputStream fstream = new FileInputStream(file); + DataInputStream in = new DataInputStream(fstream); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + ) + { + String line = br.readLine(); + + id = Integer.parseInt(line); + } + catch (Exception e) + { + System.out.println("Error: Raid World GetId Read Exception"); + } + } + + try ( + FileWriter fstream = new FileWriter(file); + BufferedWriter out = new BufferedWriter(fstream); + ) + { + out.write("" + (id + 1)); + } + catch (Exception e) + { + System.out.println("Error: Game World GetId Re-Write Exception"); + } + + return id; + } + + public List getDataLocs(String data) + { + if (!DataLocs.containsKey(data)) + { + return new ArrayList<>(); + } + + return DataLocs.get(data); + } + + public List getCustomLocs(String id) + { + if (!CustomLocs.containsKey(id)) + { + return new ArrayList<>(); + } + + return CustomLocs.get(id); + } + + public Map> getAllCustomLocs() + { + return CustomLocs; + } + + public Map> getAllDataLocs() + { + return DataLocs; + } + + public Location getRandomXZ() + { + Location loc = new Location(World, 0, 250, 0); + + int xVar = MaxX - MinX; + int zVar = MaxZ - MinZ; + + loc.setX(MinX + UtilMath.r(xVar)); + loc.setZ(MinZ + UtilMath.r(zVar)); + + return loc; + } + + public String get(String key) + { + return _dataEntries.get(key); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/command/StartRaidCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/command/StartRaidCommand.java new file mode 100644 index 00000000..be755626 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/command/StartRaidCommand.java @@ -0,0 +1,41 @@ +package mineplex.game.clans.clans.worldevent.raid.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.raid.RaidManager; +import mineplex.game.clans.clans.worldevent.raid.RaidType; + +public class StartRaidCommand extends CommandBase +{ + public StartRaidCommand(RaidManager plugin) + { + super(plugin, RaidManager.Perm.START_RAID_COMMAND, "startraid"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: /startraid ")); + return; + } + try + { + RaidType type = RaidType.valueOf(args[0]); + Plugin.startRaid(caller, type); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "That is not an existing raid type. Raids:")); + for (RaidType type : RaidType.values()) + { + UtilPlayer.message(caller, C.cGray + " - " + C.cYellow + type.name()); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/WitherRaid.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/WitherRaid.java new file mode 100644 index 00000000..6eb3a411 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/WitherRaid.java @@ -0,0 +1,114 @@ +package mineplex.game.clans.clans.worldevent.raid.wither; + +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidManager; +import mineplex.game.clans.clans.worldevent.raid.RaidType; +import mineplex.game.clans.clans.worldevent.raid.RaidWorldEvent; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.five.ChallengeFive; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.four.ChallengeFour; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.one.ChallengeOne; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.seven.ChallengeSeven; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.three.ChallengeThree; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.two.ChallengeTwo; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; + +public class WitherRaid extends RaidWorldEvent +{ + private List>> _challenges; + private RaidChallenge _currentChallenge; + + public WitherRaid(mineplex.game.clans.clans.worldevent.raid.WorldData data, RaidManager manager) + { + super(RaidType.CHARLES_WITHERTON.getRaidName(), data, manager); + } + + private void nextChallenge() + { + _currentChallenge = null; + + if (_challenges.isEmpty()) + { + return; + } + + Class> clazz = _challenges.remove(0); + try + { + _currentChallenge = clazz.getConstructor(WitherRaid.class).newInstance(this); + _currentChallenge.start(); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) + { + e.printStackTrace(); + } + } + + private void teleportToAltar() + { + Location altar = WorldData.getCustomLocs("MAIN_ALTAR").get(0); + getPlayers().forEach(player -> player.teleport(altar)); + } + + @Override + protected void customLoad() + { + WorldData.World.setGameRuleValue("doDaylightCycle", "false"); + WorldData.World.setTime(14000); + _challenges = new LinkedList<>(); + _challenges.add(ChallengeOne.class); + _challenges.add(ChallengeTwo.class); + _challenges.add(ChallengeThree.class); + _challenges.add(ChallengeFour.class); + _challenges.add(ChallengeFive.class); + _challenges.add(ChallengeSix.class); + _challenges.add(ChallengeSeven.class); + } + + @Override + protected void afterTeleportIn() + { + nextChallenge(); + } + + @Override + protected void customTick() + { + if (_currentChallenge != null) + { + if (_currentChallenge.isComplete()) + { + if (_challenges.size() < 5) + { + teleportToAltar(); + } + nextChallenge(); + } + } + } + + @Override + protected void customStop() + { + if (_currentChallenge != null) + { + _currentChallenge.complete(false); + } + } + + @EventHandler + public void onBlockToss(SkillTriggerEvent event) + { + if (event.GetSkillName().equals("Block Toss") && getPlayers().contains(event.GetPlayer())) + { + event.SetCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/five/ChallengeFive.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/five/ChallengeFive.java new file mode 100644 index 00000000..e5ee9975 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/five/ChallengeFive.java @@ -0,0 +1,185 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.five; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.archer.DecayingArcher; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.corpse.ReanimatedCorpse; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.giant.Goliath; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; + +public class ChallengeFive extends RaidChallenge +{ + private Location _altar; + private boolean _teleported = false; + private LinkedList _gates = new LinkedList<>(); + private Goliath _goliath; + + public ChallengeFive(WitherRaid raid) + { + super(raid, "Rapid Escape"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + } + + private void teleportIn() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Run!")); + player.teleport(getRaid().getWorldData().getCustomLocs("C_FIVE_ENTER").get(0)); + }); + } + + @Override + public void customStart() + { + int i = 1; + while (getRaid().getWorldData().getAllCustomLocs().containsKey("C_FIVE_G" + i)) + { + List> creatures = new ArrayList<>(); + for (Location loc : getRaid().getWorldData().getCustomLocs("C_FIVE_G" + i + "G")) + { + int type = UtilMath.r(3) + 1; + if (type == 1) + { + UndeadKnight knight = new UndeadKnight(this, loc); + getRaid().registerCreature(knight); + creatures.add(knight); + } + if (type == 2) + { + ReanimatedCorpse corpse = new ReanimatedCorpse(this, loc); + getRaid().registerCreature(corpse); + creatures.add(corpse); + } + if (type == 3) + { + DecayingArcher archer = new DecayingArcher(this, loc); + getRaid().registerCreature(archer); + creatures.add(archer); + } + } + _gates.add(new IronGate(this, getRaid().getWorldData().getCustomLocs("C_FIVE_G" + i), creatures)); + i++; + } + _goliath = new Goliath(this, getRaid().getWorldData().getCustomLocs("C_FIVE_GIANT").get(0)); + getRaid().registerCreature(_goliath); + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Use the third gate!"))); + } + + @SuppressWarnings("deprecation") + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "You made it!")); + player.teleport(_altar); + }); + ClansManager.getInstance().getBlockRestore().restore(getRaid().getWorldData().getCustomLocs("GATE_THREE").get(0).getBlock().getRelative(BlockFace.DOWN)); + getRaid().getWorldData().getCustomLocs("GATE_THREE").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN); + Block gate = getRaid().getWorldData().getCustomLocs("GATE_FOUR").get(0).getBlock(); + ClansManager.getInstance().getBlockRestore().restore(gate); + ClansManager.getInstance().getBlockRestore().restore(gate.getRelative(BlockFace.DOWN)); + gate.getRelative(BlockFace.DOWN).setType(Material.GLOWSTONE); + gate.setType(Material.SKULL); + gate.setData((byte)1); + _altar.getWorld().dropItem(_altar.clone().add(0, 2, 0), new ItemStack(Material.EMERALD, UtilMath.rRange(15, 17))); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC) + { + for (Player player : getRaid().getPlayers()) + { + if (UtilMath.offset(player.getLocation(), getRaid().getWorldData().getCustomLocs("C_FIVE_EXIT").get(0)) <= 3) + { + complete(); + return; + } + } + } + if (event.getType() == UpdateType.TICK) + { + if (!_gates.isEmpty() && _teleported) + { + IronGate gate = _gates.peek(); + if (UtilMath.offset2d(_goliath.getEntity().getLocation(), gate.getCenter()) > 5) + { + Location to = gate.getCenter().clone(); + to.setY(_goliath.getEntity().getLocation().getY()); + _goliath.getEntity().setVelocity(UtilAlg.getTrajectory(_goliath.getEntity().getLocation(), to).normalize().multiply(0.15)); + } + if (gate.update()) + { + _gates.poll(); + } + } + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + + Block clicked = event.getClickedBlock(); + if (!_teleported) + { + if (clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_THREE").get(0).getBlock()) || clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_THREE").get(0).getBlock().getRelative(BlockFace.DOWN))) + { + _teleported = true; + teleportIn(); + } + } + } + + @EventHandler + public void onIcePrison(SkillTriggerEvent event) + { + if (getRaid().getPlayers().contains(event.GetPlayer()) && _teleported && (event.GetSkillName().equals("Ice Prison") || event.GetSkillName().equals("Fissure"))) + { + event.SetCancelled(true); + } + } + + @EventHandler + public void onDeath(EventCreatureDeathEvent event) + { + if (event.getCreature().getEvent() instanceof WitherRaid) + { + if (((WitherRaid)event.getCreature().getEvent()).getId() == getRaid().getId()) + { + _gates.forEach(gate -> gate.handleDeath(event.getCreature())); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/five/IronGate.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/five/IronGate.java new file mode 100644 index 00000000..5b42168b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/five/IronGate.java @@ -0,0 +1,81 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.five; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; + +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventCreature; + +public class IronGate +{ + private ChallengeFive _challenge; + private List _corners; + private List> _guardians; + + public IronGate(ChallengeFive challenge, List corners, List> guardians) + { + _challenge = challenge; + _corners = corners; + _guardians = guardians; + } + + private void open() + { + Location pos1 = _corners.get(0); + Location pos2 = _corners.get(1); + int minX = Math.min(pos1.getBlockX(), pos2.getBlockX()); + int maxX = Math.max(pos1.getBlockX(), pos2.getBlockX()); + int minY = Math.min(pos1.getBlockY(), pos2.getBlockY()); + int maxY = Math.max(pos1.getBlockY(), pos2.getBlockY()) + 3; + int minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); + int maxZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ()); + + for (int x = minX; x <= maxX; x++) + { + for (int y = minY; y <= maxY; y++) + { + for (int z = minZ; z <= maxZ; z++) + { + Block block = _challenge.getRaid().getWorldData().World.getBlockAt(x, y, z); + ClansManager.getInstance().getBlockRestore().restore(block); + if (block.getType() == Material.IRON_FENCE) + { + block.setType(Material.AIR); + } + } + } + } + } + + public Location getCenter() + { + Location pos1 = _corners.get(0); + Location pos2 = _corners.get(1); + int minX = Math.min(pos1.getBlockX(), pos2.getBlockX()); + int maxX = Math.max(pos1.getBlockX(), pos2.getBlockX()); + int minY = Math.min(pos1.getBlockY(), pos2.getBlockY()); + int maxY = Math.max(pos1.getBlockY(), pos2.getBlockY()) + 3; + int minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); + int maxZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ()); + + return new Location(_challenge.getRaid().getWorldData().World, minX + ((maxX - minX) / 2), minY + ((maxY - minY) / 2), minZ + ((maxZ - minZ) / 2)); + } + + public boolean update() + { + if (_guardians.size() < 1) + { + open(); + return true; + } + return false; + } + + public void handleDeath(EventCreature creature) + { + _guardians.remove(creature); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/four/ChallengeFour.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/four/ChallengeFour.java new file mode 100644 index 00000000..8a0459fa --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/four/ChallengeFour.java @@ -0,0 +1,135 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.four; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; + +public class ChallengeFour extends RaidChallenge +{ + private Location _altar; + private boolean _teleported = false; + private List _blocks = new ArrayList<>(); + private double[] _damageYRange = new double[2]; + + public ChallengeFour(WitherRaid raid) + { + super(raid, "Infested Pits"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + } + + private void teleportIn() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Complete the parkour!")); + player.teleport(getRaid().getWorldData().getCustomLocs("C_FOUR_ENTER").get(0)); + }); + } + + @Override + public void customStart() + { + for (Location loc : getRaid().getWorldData().getCustomLocs("C_FOUR_FB")) + { + loc.getBlock().setType(Material.NETHER_BRICK); + _blocks.add(new FakeBlock(this, loc.getBlock())); + } + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Use the second gate!"))); + Location pos1 = getRaid().getWorldData().getCustomLocs("C_FOUR_SF").get(0); + Location pos2 = getRaid().getWorldData().getCustomLocs("C_FOUR_SF").get(1); + _damageYRange[0] = Math.min(pos1.getY(), pos2.getY()); + _damageYRange[1] = Math.max(pos1.getY(), pos2.getY()); + } + + @SuppressWarnings("deprecation") + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Excellent jumping!")); + player.teleport(_altar); + }); + ClansManager.getInstance().getBlockRestore().restore(getRaid().getWorldData().getCustomLocs("GATE_TWO").get(0).getBlock().getRelative(BlockFace.DOWN)); + getRaid().getWorldData().getCustomLocs("GATE_TWO").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN); + Block gate = getRaid().getWorldData().getCustomLocs("GATE_THREE").get(0).getBlock(); + ClansManager.getInstance().getBlockRestore().restore(gate); + ClansManager.getInstance().getBlockRestore().restore(gate.getRelative(BlockFace.DOWN)); + gate.getRelative(BlockFace.DOWN).setType(Material.GLOWSTONE); + gate.setType(Material.SKULL); + gate.setData((byte)1); + _altar.getWorld().dropItem(_altar.clone().add(0, 2, 0), new ItemStack(Material.EMERALD, UtilMath.rRange(13, 17))); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC && _teleported) + { + for (Player player : getRaid().getPlayers()) + { + if (UtilMath.offset(player.getLocation(), getRaid().getWorldData().getCustomLocs("C_FOUR_EXIT").get(0)) <= 3) + { + complete(); + return; + } + if (player.getLocation().getY() <= _damageYRange[1] && player.getLocation().getY() >= _damageYRange[0]) + { + getRaid().getDamageManager().NewDamageEvent(player, null, null, DamageCause.LAVA, 1, false, true, true, "Burning Cavern", "Hot Ground"); + } + } + } + if (event.getType() == UpdateType.TICK) + { + _blocks.forEach(FakeBlock::update); + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + + Block clicked = event.getClickedBlock(); + if (!_teleported) + { + if (clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_TWO").get(0).getBlock()) || clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_TWO").get(0).getBlock().getRelative(BlockFace.DOWN))) + { + _teleported = true; + teleportIn(); + } + } + } + + @EventHandler + public void onIcePrison(SkillTriggerEvent event) + { + if (getRaid().getPlayers().contains(event.GetPlayer()) && _teleported) + { + event.SetCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/four/FakeBlock.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/four/FakeBlock.java new file mode 100644 index 00000000..a14a2abc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/four/FakeBlock.java @@ -0,0 +1,42 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.four; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import mineplex.game.clans.clans.ClansManager; + +public class FakeBlock +{ + private ChallengeFour _challenge; + private Block _block; + + public FakeBlock(ChallengeFour challenge, Block block) + { + _challenge = challenge; + _block = block; + _block.setType(Material.NETHER_BRICK); + } + + public void update() + { + boolean aired = false; + for (Player player : _challenge.getRaid().getPlayers()) + { + if (player.getLocation().getBlock().getRelative(BlockFace.DOWN).equals(_block)) + { + ClansManager.getInstance().getBlockRestore().restore(_block); + _block.setType(Material.AIR); + aired = true; + break; + } + } + + if (!aired) + { + ClansManager.getInstance().getBlockRestore().restore(_block); + _block.setType(Material.NETHER_BRICK); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/one/ChallengeOne.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/one/ChallengeOne.java new file mode 100644 index 00000000..0447604d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/one/ChallengeOne.java @@ -0,0 +1,108 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.one; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; + +public class ChallengeOne extends RaidChallenge +{ + private Location _altar; + private Player _trigger; + + public ChallengeOne(WitherRaid raid) + { + super(raid, "Entering Hell"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + } + + private void sealDoor() + { + Location doorBase1 = getRaid().getWorldData().getCustomLocs("C_ONE_TRAP").get(0); + Location doorBase2 = getRaid().getWorldData().getCustomLocs("C_ONE_TRAP").get(1); + int minX = Math.min(doorBase1.getBlockX(), doorBase2.getBlockX()); + int maxX = Math.max(doorBase1.getBlockX(), doorBase2.getBlockX()); + int minY = Math.min(doorBase1.getBlockY(), doorBase2.getBlockY()); + int maxY = Math.max(doorBase1.getBlockY(), doorBase2.getBlockY()) + 1; + int minZ = Math.min(doorBase1.getBlockZ(), doorBase2.getBlockZ()); + int maxZ = Math.max(doorBase1.getBlockZ(), doorBase2.getBlockZ()); + + for (int x = minX; x <= maxX; x++) + { + for (int y = minY; y <= maxY; y++) + { + for (int z = minZ; z <= maxZ; z++) + { + Block block = getRaid().getWorldData().World.getBlockAt(x, y, z); + ClansManager.getInstance().getBlockRestore().restore(block); + block.setType(Material.NETHER_BRICK); + } + } + } + } + + private void setupStoneBrickTraps() + { + for (Location loc : getRaid().getWorldData().getCustomLocs("C_ONE_SBT")) + { + Block b = loc.getBlock(); + ClansManager.getInstance().getBlockRestore().restore(b); + b.setType(Material.SMOOTH_BRICK); + ClansManager.getInstance().getBlockRestore().restore(b.getRelative(BlockFace.UP)); + b.getRelative(BlockFace.UP).setType(Material.SMOOTH_BRICK); + } + } + + @Override + public void customStart() + { + setupStoneBrickTraps(); + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Enter the Altar Room"))); + } + + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> + { + player.getWorld().strikeLightningEffect(player.getLocation()); + if (_trigger != null) + { + if (UtilMath.offset(player.getLocation(), _altar) >= 17) + { + player.teleport(_trigger); + } + } + }); + sealDoor(); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC) + { + for (Player player : getRaid().getPlayers()) + { + if (UtilMath.offset(player.getLocation(), _altar) <= 10) + { + _trigger = player; + complete(); + return; + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/seven/ChallengeSeven.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/seven/ChallengeSeven.java new file mode 100644 index 00000000..5b58dcd6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/seven/ChallengeSeven.java @@ -0,0 +1,179 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.seven; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.CharlesWitherton; +import mineplex.game.clans.items.ItemType; +import mineplex.game.clans.items.RareItemFactory; +import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute; +import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; +import mineplex.game.clans.items.attributes.weapon.SharpAttribute; +import mineplex.game.clans.items.legendaries.DemonicScythe; + +public class ChallengeSeven extends RaidChallenge +{ + private Location _altar; + private boolean _teleported = false; + private boolean _bottomLayer = false; + private CharlesWitherton _charlie; + private long _lastKnightRespawn; + + public ChallengeSeven(WitherRaid raid) + { + super(raid, "The Final Battle"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + } + + private void teleportToBottom() + { + _charlie.getEntity().teleport(getRaid().getWorldData().getCustomLocs("C_SEVEN_RWC").get(0)); + for (Player player : getRaid().getPlayers()) + { + player.teleport(getRaid().getWorldData().getCustomLocs("C_SEVEN_RWC").get(0)); + } + } + + private void teleportIn() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName(), "GUARDS! ATTACK!")); + player.teleport(getRaid().getWorldData().getCustomLocs("C_SEVEN_ENTER").get(0)); + }); + for (Location loc : getRaid().getWorldData().getCustomLocs("C_SEVEN_UK")) + { + getRaid().registerCreature(new UndeadKnight(this, loc)); + } + _lastKnightRespawn = System.currentTimeMillis(); + _charlie = new CharlesWitherton(this, getRaid().getWorldData().getCustomLocs("C_SEVEN_CHARLES").get(0)); + getRaid().registerCreature(_charlie); + for (Location loc : getRaid().getWorldData().getCustomLocs("C_SEVEN_UK")) + { + getRaid().registerCreature(new UndeadKnight(this, loc)); + } + } + + @Override + public void customStart() + { + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Use the final gate!"))); + } + + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "The evil reign of Charles Witherton is over! You will be returned to spawn in 2 minutes!")); + player.teleport(_altar); + }); + List anim = UtilShapes.getPointsInCircle(_altar.clone().add(0, 2, 0), 5, 3); + int emeralds = UtilMath.rRange((int)Math.ceil(45 / anim.size()), (int)Math.ceil(80 / anim.size())); + for (Location drop : anim) + { + ClansManager.getInstance().getLootManager().dropRaid(drop); + drop.getWorld().dropItem(drop, new ItemStack(Material.EMERALD, emeralds)); + } + if (Math.random() <= 0.03) + { + RareItemFactory mainFactory = RareItemFactory.begin(ItemType.LEGENDARY).setLegendary(DemonicScythe.class); + if (Math.random() < 0.1) + { + mainFactory.setSuperPrefix(FlamingAttribute.class); + mainFactory.setPrefix(SharpAttribute.class); + mainFactory.setSuffix(ConqueringAttribute.class); + } + _altar.getWorld().dropItem(_altar.clone().add(0, 2, 0), mainFactory.fabricate()); + } + ClansManager.getInstance().getBlockRestore().restore(getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock().getRelative(BlockFace.DOWN)); + getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN); + getRaid().setForceEnd(System.currentTimeMillis() + UtilTime.convert(2, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); + } + + @EventHandler + public void onDeath(EventCreatureDeathEvent event) + { + if (event.getCreature() instanceof CharlesWitherton) + { + if (((WitherRaid)event.getCreature().getEvent()).getId() == getRaid().getId()) + { + complete(); + } + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + + Block clicked = event.getClickedBlock(); + if (!_teleported) + { + if (clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock()) || clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock().getRelative(BlockFace.DOWN))) + { + _teleported = true; + teleportIn(); + } + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC) + { + if (_teleported && !_bottomLayer && _charlie != null) + { + if (_charlie.getHealthPercent() <= 0.75) + { + _bottomLayer = true; + teleportToBottom(); + return; + } + + if (UtilTime.elapsed(_lastKnightRespawn, 30000)) + { + _lastKnightRespawn = System.currentTimeMillis(); + long knights = getRaid().getCreatures().stream().filter(UndeadKnight.class::isInstance).count(); + int total = getRaid().getWorldData().getCustomLocs("C_SEVEN_UK").size(); + if (knights < total) + { + long needed = total - knights; + for (int i = 0; i < needed; i++) + { + Location loc = getRaid().getWorldData().getCustomLocs("C_SEVEN_UK").get(i); + getRaid().registerCreature(new UndeadKnight(this, loc)); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/six/ChallengeSix.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/six/ChallengeSix.java new file mode 100644 index 00000000..2face28d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/six/ChallengeSix.java @@ -0,0 +1,98 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.six; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.magma.Magmus; + +public class ChallengeSix extends RaidChallenge +{ + private Location _altar; + private boolean _teleported = false; + + public ChallengeSix(WitherRaid raid) + { + super(raid, "Fiery Gates"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + } + + private void teleportIn() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Slay the gatekeeper or perish!")); + player.teleport(getRaid().getWorldData().getCustomLocs("C_SIX_ENTER").get(0)); + }); + getRaid().registerCreature(new Magmus(this, getRaid().getWorldData().getCustomLocs("C_SIX_MCS").get(0))); + } + + @Override + public void customStart() + { + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Use the fourth gate!"))); + } + + @SuppressWarnings("deprecation") + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Your final battle awaits!")); + player.teleport(_altar); + }); + ClansManager.getInstance().getBlockRestore().restore(getRaid().getWorldData().getCustomLocs("GATE_FOUR").get(0).getBlock().getRelative(BlockFace.DOWN)); + getRaid().getWorldData().getCustomLocs("GATE_FOUR").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN); + Block gate = getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock(); + ClansManager.getInstance().getBlockRestore().restore(gate); + ClansManager.getInstance().getBlockRestore().restore(gate.getRelative(BlockFace.DOWN)); + gate.getRelative(BlockFace.DOWN).setType(Material.GLOWSTONE); + gate.setType(Material.SKULL); + gate.setData((byte)1); + _altar.getWorld().dropItem(_altar.clone().add(0, 2, 0), new ItemStack(Material.EMERALD, UtilMath.rRange(15, 20))); + } + + @EventHandler + public void onDeath(EventCreatureDeathEvent event) + { + if (event.getCreature() instanceof Magmus) + { + if (((WitherRaid)event.getCreature().getEvent()).getId() == getRaid().getId()) + { + complete(); + } + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + + Block clicked = event.getClickedBlock(); + if (!_teleported) + { + if (clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_FOUR").get(0).getBlock()) || clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_FOUR").get(0).getBlock().getRelative(BlockFace.DOWN))) + { + _teleported = true; + teleportIn(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/three/ChallengeThree.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/three/ChallengeThree.java new file mode 100644 index 00000000..a0f6d289 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/three/ChallengeThree.java @@ -0,0 +1,140 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.three; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.archer.DecayingArcher; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.corpse.ReanimatedCorpse; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadMage; + +public class ChallengeThree extends RaidChallenge +{ + private Location _altar; + private boolean _teleported = false; + private List _torches = new ArrayList<>(); + protected int LitTorches; + private long _lastSpawn; + private int _spawnTotal; + + public ChallengeThree(WitherRaid raid) + { + super(raid, "Light The Fires"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + LitTorches = 0; + } + + private void teleportIn() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Light the torches!")); + player.teleport(getRaid().getWorldData().getCustomLocs("C_THREE_ENTER").get(0)); + }); + getRaid().registerCreature(new UndeadMage(this, getRaid().getWorldData().getCustomLocs("C_THREE_UM").get(0), true, getRaid().getWorldData().getCustomLocs("C_THREE_UMS"), getRaid().getWorldData().getCustomLocs("C_THREE_UMT"))); + } + + @Override + public void customStart() + { + for (Location loc : getRaid().getWorldData().getCustomLocs("C_THREE_TORCH")) + { + ClansManager.getInstance().getBlockRestore().restore(loc.getBlock()); + loc.getBlock().setType(Material.NETHERRACK); + _torches.add(new ChallengeTorch(this, loc.getBlock())); + } + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "Use the first gate!"))); + } + + @SuppressWarnings("deprecation") + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "The Torches are lit!")); + player.teleport(_altar); + }); + ClansManager.getInstance().getBlockRestore().restore(getRaid().getWorldData().getCustomLocs("GATE_ONE").get(0).getBlock().getRelative(BlockFace.DOWN)); + getRaid().getWorldData().getCustomLocs("GATE_ONE").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN); + Block gate = getRaid().getWorldData().getCustomLocs("GATE_TWO").get(0).getBlock(); + ClansManager.getInstance().getBlockRestore().restore(gate); + ClansManager.getInstance().getBlockRestore().restore(gate.getRelative(BlockFace.DOWN)); + gate.getRelative(BlockFace.DOWN).setType(Material.GLOWSTONE); + gate.setType(Material.SKULL); + gate.setData((byte)1); + _altar.getWorld().dropItem(_altar.clone().add(0, 2, 0), new ItemStack(Material.EMERALD, UtilMath.rRange(10, 15))); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC) + { + if (LitTorches >= 4) + { + complete(); + } + } + if (event.getType() == UpdateType.TICK) + { + _torches.forEach(ChallengeTorch::update); + if (UtilTime.elapsed(_lastSpawn, 7000) && _teleported) + { + _lastSpawn = System.currentTimeMillis(); + if (_spawnTotal > 100) + { + return; + } + getRaid().getWorldData().getCustomLocs("C_THREE_RC").forEach(loc -> + { + _spawnTotal++; + getRaid().registerCreature(new ReanimatedCorpse(this, loc)); + }); + getRaid().getWorldData().getCustomLocs("C_THREE_DA").forEach(loc -> + { + _spawnTotal++; + getRaid().registerCreature(new DecayingArcher(this, loc)); + }); + } + } + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (!event.hasBlock()) + { + return; + } + + Block clicked = event.getClickedBlock(); + if (!_teleported) + { + if (clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_ONE").get(0).getBlock()) || clicked.equals(getRaid().getWorldData().getCustomLocs("GATE_ONE").get(0).getBlock().getRelative(BlockFace.DOWN))) + { + _lastSpawn = System.currentTimeMillis(); + _teleported = true; + teleportIn(); + } + } + _torches.forEach(torch -> torch.handleInteract(clicked)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/three/ChallengeTorch.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/three/ChallengeTorch.java new file mode 100644 index 00000000..5426cf44 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/three/ChallengeTorch.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.three; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +import mineplex.game.clans.clans.ClansManager; + +public class ChallengeTorch +{ + private ChallengeThree _challenge; + private Block _block; + private long _extinguish; + + public ChallengeTorch(ChallengeThree challenge, Block block) + { + _challenge = challenge; + _block = block; + _extinguish = -1; + } + + public void handleInteract(Block block) + { + if (block.equals(_block) && _extinguish == -1) + { + _challenge.LitTorches++; + _extinguish = System.currentTimeMillis() + 3000; + ClansManager.getInstance().getBlockRestore().restore(_block.getRelative(BlockFace.UP)); + _block.getRelative(BlockFace.UP).setType(Material.FIRE); + } + } + + public void update() + { + if (_extinguish != -1 && !_challenge.isComplete()) + { + if (_extinguish < System.currentTimeMillis()) + { + _extinguish = -1; + _challenge.LitTorches--; + ClansManager.getInstance().getBlockRestore().restore(_block.getRelative(BlockFace.UP)); + _block.getRelative(BlockFace.UP).setType(Material.AIR); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/two/ChallengeTwo.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/two/ChallengeTwo.java new file mode 100644 index 00000000..3c205ff5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/challenge/two/ChallengeTwo.java @@ -0,0 +1,77 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.challenge.two; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadMage; + +public class ChallengeTwo extends RaidChallenge +{ + private Location _altar; + + public ChallengeTwo(WitherRaid raid) + { + super(raid, "Undead Encounter"); + + _altar = raid.getWorldData().getCustomLocs("MAIN_ALTAR").get(0); + } + + private void openStoneBrickTraps() + { + for (Location loc : getRaid().getWorldData().getCustomLocs("C_ONE_SBT")) + { + Block b = loc.getBlock(); + ClansManager.getInstance().getBlockRestore().restore(b); + b.setType(Material.AIR); + ClansManager.getInstance().getBlockRestore().restore(b.getRelative(BlockFace.UP)); + b.getRelative(BlockFace.UP).setType(Material.AIR); + getRaid().registerCreature(new UndeadKnight(this, loc)); + } + } + + @SuppressWarnings("deprecation") + @Override + public void customStart() + { + openStoneBrickTraps(); + _altar.getBlock().getRelative(BlockFace.DOWN).setData(DyeColor.BLACK.getWoolData()); + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main("Undead Mage", "MINIONS, ATTACK!"))); + getRaid().registerCreature(new UndeadMage(this, _altar, false, getRaid().getWorldData().getCustomLocs("C_ONE_SBT"), getRaid().getWorldData().getCustomLocs("C_TWO_MTP"))); + } + + @SuppressWarnings("deprecation") + @Override + public void customComplete() + { + getRaid().getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getRaid().getName() + " Raid", "The Undead Mage has fallen!"))); + Block gate = getRaid().getWorldData().getCustomLocs("GATE_ONE").get(0).getBlock(); + ClansManager.getInstance().getBlockRestore().restore(gate); + ClansManager.getInstance().getBlockRestore().restore(gate.getRelative(BlockFace.DOWN)); + gate.getRelative(BlockFace.DOWN).setType(Material.GLOWSTONE); + gate.setType(Material.SKULL); + gate.setData((byte)1); + } + + @EventHandler + public void onDeath(EventCreatureDeathEvent event) + { + if (event.getCreature() instanceof UndeadMage) + { + if (((WitherRaid)event.getCreature().getEvent()).getId() == getRaid().getId()) + { + complete(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/archer/ArcherShooting.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/archer/ArcherShooting.java new file mode 100644 index 00000000..9bf61cb2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/archer/ArcherShooting.java @@ -0,0 +1,95 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.archer; + +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class ArcherShooting extends BossAbility +{ + private long _lastShoot; + private long _lastRope; + + public ArcherShooting(DecayingArcher creature) + { + super(creature); + + _lastShoot = System.currentTimeMillis(); + _lastRope = System.currentTimeMillis(); + } + + @Override + public void tick() + { + if (getEntity().getTarget() != null && getEntity().getTarget() instanceof Player) + { + if (UtilTime.elapsed(_lastRope, 10000)) + { + _lastRope = System.currentTimeMillis(); + UtilEnt.LookAt(getEntity(), getEntity().getTarget().getEyeLocation()); + UtilEnt.addFlag(getEntity().launchProjectile(Arrow.class), "ROPED_ARROW"); + return; + } + if (UtilTime.elapsed(_lastShoot, 2000)) + { + _lastShoot = System.currentTimeMillis(); + UtilEnt.LookAt(getEntity(), getEntity().getTarget().getEyeLocation()); + getEntity().launchProjectile(Arrow.class); + } + } + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE) == null) + { + return; + } + LivingEntity ent = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (ent.getEntityId() == getEntity().getEntityId()) + { + if (event.GetCause() != DamageCause.PROJECTILE) + { + event.SetCancelled("Archer Only"); + return; + } + if (UtilEnt.hasFlag(event.GetProjectile(), "ROPED_ARROW")) + { + ent.setVelocity(UtilAlg.getTrajectory(ent, event.GetDamageeEntity()).normalize()); + event.AddMod("Roped Arrow", -event.GetDamage()); + return; + } + event.AddMod("Ranged Attack", 2 - event.GetDamage()); + } + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return false; + } + + @Override + public void setFinished() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/archer/DecayingArcher.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/archer/DecayingArcher.java new file mode 100644 index 00000000..e7215b1a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/archer/DecayingArcher.java @@ -0,0 +1,86 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.archer; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class DecayingArcher extends RaidCreature +{ + private RaidChallenge _challenge; + private ArcherShooting _passive; + + public DecayingArcher(RaidChallenge challenge, Location location) + { + super(challenge.getRaid(), location, "Decaying Archer", true, 10, 100, true, Zombie.class); + + _challenge = challenge; + spawnEntity(); + _passive = new ArcherShooting(this); + } + + @Override + protected void spawnCustom() + { + getEntity().getEquipment().setItemInHand(new ItemStack(Material.BOW)); + getEntity().getEquipment().setItemInHandDropChance(0f); + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + HandlerList.unregisterAll(_passive); + _passive = null; + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + _passive.tick(); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/corpse/CorpsePassive.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/corpse/CorpsePassive.java new file mode 100644 index 00000000..f08d0ed3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/corpse/CorpsePassive.java @@ -0,0 +1,43 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.corpse; + +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class CorpsePassive extends BossPassive +{ + public CorpsePassive(ReanimatedCorpse creature) + { + super(creature); + } + + @Override + public int getCooldown() + { + return 0; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() {} + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamagerEntity(false) == null) + { + return; + } + if (event.GetDamagerEntity(false).getEntityId() == getEntity().getEntityId()) + { + event.AddMod("Corpse Attack", 1 - event.GetDamage()); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/corpse/ReanimatedCorpse.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/corpse/ReanimatedCorpse.java new file mode 100644 index 00000000..e09e61ea --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/corpse/ReanimatedCorpse.java @@ -0,0 +1,88 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.corpse; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class ReanimatedCorpse extends RaidCreature +{ + private static final Material[] SWORDS = {Material.WOOD_SWORD, Material.STONE_SWORD, Material.GOLD_SWORD, Material.IRON_SWORD, Material.DIAMOND_SWORD}; + private RaidChallenge _challenge; + private CorpsePassive _passive; + + public ReanimatedCorpse(RaidChallenge challenge, Location location) + { + super(challenge.getRaid(), location, "Reanimated Corpse", true, 15, 100, true, Zombie.class); + + _challenge = challenge; + spawnEntity(); + _passive = new CorpsePassive(this); + } + + @Override + protected void spawnCustom() + { + getEntity().getEquipment().setItemInHand(new ItemStack(UtilMath.randomElement(SWORDS))); + getEntity().getEquipment().setItemInHandDropChance(0f); + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + HandlerList.unregisterAll(_passive); + _passive = null; + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + _passive.tick(); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/giant/Goliath.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/giant/Goliath.java new file mode 100644 index 00000000..1920ef4a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/giant/Goliath.java @@ -0,0 +1,80 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.giant; + +import org.bukkit.Location; +import org.bukkit.entity.Giant; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class Goliath extends RaidCreature +{ + private RaidChallenge _challenge; + private GoliathPassive _passive; + + public Goliath(RaidChallenge challenge, Location location) + { + super(challenge.getRaid(), location, "Goliath", true, 5000, 500, true, Giant.class); + + _challenge = challenge; + spawnEntity(); + _passive = new GoliathPassive(this); + } + + @Override + protected void spawnCustom() {} + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + HandlerList.unregisterAll(_passive); + _passive = null; + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + _passive.tick(); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/giant/GoliathPassive.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/giant/GoliathPassive.java new file mode 100644 index 00000000..1551a9fc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/giant/GoliathPassive.java @@ -0,0 +1,60 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.giant; + +import org.bukkit.entity.Giant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class GoliathPassive extends BossPassive +{ + public GoliathPassive(Goliath creature) + { + super(creature); + } + + @Override + public int getCooldown() + { + return 0; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + for (Player player : ((WitherRaid)getBoss().getEvent()).getPlayers()) + { + if (UtilPlayer.isSpectator(player) || player.isDead() || !player.isValid()) + { + continue; + } + if (UtilMath.offset(getEntity(), player) <= 7) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.ENTITY_ATTACK, 100, false, true, true, getEntity().getName(), "Smash"); + } + } + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity() != null) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + event.SetCancelled("Giant Invulnerability"); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/KnightPassive.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/KnightPassive.java new file mode 100644 index 00000000..825254c8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/KnightPassive.java @@ -0,0 +1,67 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityShootBowEvent; + +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class KnightPassive extends BossPassive +{ + private long _lastUsed; + + public KnightPassive(UndeadKnight creature) + { + super(creature); + + _lastUsed = System.currentTimeMillis(); + } + + @Override + public int getCooldown() + { + return 12; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() {} + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamagerEntity(false) == null) + { + return; + } + if (event.GetDamagerEntity(false).getEntityId() == getEntity().getEntityId()) + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _lastUsed = System.currentTimeMillis(); + event.AddMod("Hilt Smash", 4 - event.GetDamage()); + getBoss().getEvent().getCondition().Factory().Slow("Hilt Smash", event.GetDamageeEntity(), event.GetDamagerEntity(false), 2, 1, false, true, false, true); + } + else + { + event.AddMod("Knight Attack", 4 - event.GetDamage()); + } + } + } + + @EventHandler + public void onShoot(EntityShootBowEvent event) + { + if (event.getEntity().getEntityId() == getEntity().getEntityId()) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBlink.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBlink.java new file mode 100644 index 00000000..2974f216 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBlink.java @@ -0,0 +1,67 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class MageBlink extends BossPassive +{ + private List _spots; + private long _lastUsed; + + public MageBlink(UndeadMage creature, List teleportSpots) + { + super(creature); + + _spots = teleportSpots; + _lastUsed = System.currentTimeMillis(); + } + + @Override + public int getCooldown() + { + return 7; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _lastUsed = System.currentTimeMillis(); + List tp = null; + if (_spots != null) + { + tp = _spots.stream().filter(spot -> UtilMath.offset(getLocation(), spot) <= 10).collect(Collectors.toList()); + } + else + { + tp = getBoss().getPlayers(UtilPlayer.getInRadius(getLocation(), 10), 10).stream().map(Player::getLocation).collect(Collectors.toList()); + } + if (tp != null && !tp.isEmpty()) + { + Location to = UtilMath.randomElement(tp); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, to, null, 0, 2, ViewDist.MAX); + getEntity().teleport(to); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBolt.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBolt.java new file mode 100644 index 00000000..71f6d694 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBolt.java @@ -0,0 +1,86 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class MageBolt extends BossPassive +{ + private static final double RANGE = 10; + private long _lastUsed; + + public MageBolt(UndeadMage creature) + { + super(creature); + _lastUsed = System.currentTimeMillis(); + } + + private void shootBolt(Player target) + { + double curRange = 0; + boolean canHit = true; + + while (curRange <= RANGE) + { + Location newTarget = getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity(), target).multiply(curRange)); + + if (!UtilBlock.airFoliage(newTarget.getBlock())) + { + canHit = false; + break; + } + if (UtilMath.offset(newTarget, target.getLocation()) <= 0.9) + { + break; + } + + curRange += 0.2; + + UtilParticle.PlayParticle(ParticleType.WITCH_MAGIC, newTarget, 0, 0, 0, 0, 1, + ViewDist.MAX, UtilServer.getPlayers()); + } + + if (canHit) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 5, true, true, false, getEntity().getName(), "Mystical Energy"); + } + } + + @Override + public int getCooldown() + { + return 3; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + Player target = UtilMath.randomElement(getBoss().getPlayers(UtilPlayer.getInRadius(getLocation(), RANGE), RANGE)); + if (target != null) + { + _lastUsed = System.currentTimeMillis(); + shootBolt(target); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBoneExplode.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBoneExplode.java new file mode 100644 index 00000000..87440c68 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageBoneExplode.java @@ -0,0 +1,76 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.Managers; +import mineplex.core.blood.Blood; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class MageBoneExplode extends BossPassive +{ + private long _lastUsed; + + public MageBoneExplode(UndeadMage creature) + { + super(creature); + _lastUsed = System.currentTimeMillis(); + } + + private void explode() + { + Map nearby = UtilPlayer.getInRadius(getLocation(), 4); + for (Player near : nearby.keySet()) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(near, getEntity(), null, DamageCause.CUSTOM, 3, true, true, false, getEntity().getName(), "Bone Explosion"); + } + Managers.get(Blood.class).Effects(null, getLocation().add(0, 0.5, 0), 48, 0.8, Sound.SKELETON_HURT, 2f, 1.2f, Material.BONE, (byte) 0, 40, false); + } + + @Override + public int getCooldown() + { + return 8; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _lastUsed = System.currentTimeMillis(); + explode(); + } + } + + @EventHandler + public void Knockback(CustomDamageEvent event) + { + if (event.GetReason() == null || !event.GetReason().contains("Bone Explosion")) + { + return; + } + + if (event.GetDamagerEntity(false) == null || event.GetDamagerEntity(false).getEntityId() != getEntity().getEntityId()) + { + return; + } + + event.AddKnockback("Bone Explosion", 5); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageSummon.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageSummon.java new file mode 100644 index 00000000..3ee21f40 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/MageSummon.java @@ -0,0 +1,80 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.entity.Skeleton; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; + +public class MageSummon extends BossPassive +{ + private final int MAX_KNIGHTS; + private static final int KNIGHTS_PER_USE = 6; + private long _lastUsed; + private List _spawnLocations; + + public MageSummon(UndeadMage creature, List spawnLocations) + { + super(creature); + + _lastUsed = System.currentTimeMillis(); + MAX_KNIGHTS = spawnLocations == null ? 10 : spawnLocations.size(); + _spawnLocations = spawnLocations; + } + + private void spawnKnight() + { + Location spawn = null; + if (_spawnLocations != null) + { + spawn = UtilMath.randomElement(_spawnLocations); + } + else + { + spawn = getLocation(); + } + getBoss().getEvent().registerCreature(new UndeadKnight(getBoss().getChallenge(), spawn)); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getLocation(), null, 0, 2, ViewDist.MAX); + UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getLocation(), null, 0, 2, ViewDist.MAX); + } + + @Override + public int getCooldown() + { + return 30; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (!UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + return; + } + long amount = ((WitherRaid)getBoss().getEvent()).getCreatures().stream().filter(UndeadKnight.class::isInstance).count(); + if (amount < MAX_KNIGHTS) + { + _lastUsed = System.currentTimeMillis(); + long spawnAmount = Math.min(MAX_KNIGHTS - amount, KNIGHTS_PER_USE); + for (int i = 0; i < spawnAmount; i++) + { + spawnKnight(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/UndeadKnight.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/UndeadKnight.java new file mode 100644 index 00000000..093d3afa --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/UndeadKnight.java @@ -0,0 +1,92 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class UndeadKnight extends RaidCreature +{ + private RaidChallenge _challenge; + private KnightPassive _passive; + + public UndeadKnight(RaidChallenge challenge, Location location) + { + super(challenge.getRaid(), location, "Undead Knight", true, 25, 100, true, Skeleton.class); + + _challenge = challenge; + spawnEntity(); + _passive = new KnightPassive(this); + } + + @Override + protected void spawnCustom() + { + getEntity().getEquipment().setItemInHand(new ItemStack(Material.STONE_SWORD)); + getEntity().getEquipment().setItemInHandDropChance(0f); + getEntity().getEquipment().setHelmet(new ItemBuilder(Material.CHAINMAIL_HELMET).setUnbreakable(true).build()); + getEntity().getEquipment().setHelmetDropChance(0f); + getEntity().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 100000000, 0)); + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + HandlerList.unregisterAll(_passive); + _passive = null; + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + _passive.tick(); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/UndeadMage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/UndeadMage.java new file mode 100644 index 00000000..7a767fcd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/mage/UndeadMage.java @@ -0,0 +1,199 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.mage; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Skeleton.SkeletonType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class UndeadMage extends RaidCreature +{ + private RaidChallenge _challenge; + private List> _abilities; + private boolean _invuln; + + public UndeadMage(RaidChallenge challenge, Location location, boolean invulnerable, List spawnLocations, List blinkLocations) + { + super(challenge.getRaid(), location, "Undead Mage", true, 500, 1500, true, Skeleton.class); + + _challenge = challenge; + _invuln = invulnerable; + spawnEntity(); + _abilities = new ArrayList<>(); + _abilities.add(new MageSummon(this, spawnLocations)); + _abilities.add(new MageBlink(this, blinkLocations)); + _abilities.add(new MageBolt(this)); + _abilities.add(new MageBoneExplode(this)); + } + + @Override + protected void spawnCustom() + { + //UtilEnt.vegetate(getEntity()); + getEntity().setSkeletonType(SkeletonType.WITHER); + getEntity().getEquipment().setItemInHand(new ItemStack(Material.RECORD_6)); //Meridian Scepter + getEntity().getEquipment().setItemInHandDropChance(0f); + getEntity().getEquipment().setHelmet(new ItemBuilder(Material.GOLD_HELMET).setUnbreakable(true).build()); + getEntity().getEquipment().setChestplate(new ItemBuilder(Material.GOLD_CHESTPLATE).setUnbreakable(true).build()); + getEntity().getEquipment().setLeggings(new ItemBuilder(Material.GOLD_LEGGINGS).setUnbreakable(true).build()); + getEntity().getEquipment().setBoots(new ItemBuilder(Material.GOLD_BOOTS).setUnbreakable(true).build()); + getEntity().getEquipment().setHelmetDropChance(0f); + getEntity().getEquipment().setChestplateDropChance(0f); + getEntity().getEquipment().setLeggingsDropChance(0f); + getEntity().getEquipment().setBootsDropChance(0f); + } + + public RaidChallenge getChallenge() + { + return _challenge; + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + for (BossPassive ability : _abilities) + { + HandlerList.unregisterAll(ability); + } + _abilities.clear(); + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + _abilities.forEach(BossPassive::tick); + } + + protected List getPlayers(Map map, double maxDist) + { + return getPlayers(map, 0, maxDist); + } + + protected List getPlayers(final Map map, double minDist, double maxDist) + { + List list = new ArrayList<>(); + + for (Player p : map.keySet()) + { + if (!_challenge.getRaid().getPlayers().contains(p)) + { + continue; + } + if (map.get(p) >= minDist && map.get(p) <= maxDist) + { + list.add(p); + } + } + + Collections.sort(list, (o1, o2) -> + { + return Double.compare(map.get(o2), map.get(o1)); + }); + + return list; + } + + @EventHandler + public void onSkeletonDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + event.SetKnockback(false); + if (_invuln) + { + event.SetCancelled("Challenge Invulnerability"); + } + } + } + + @EventHandler + public void noFallDamage(CustomDamageEvent event) + { + if (getEntity() == null) + { + return; + } + + if (event.GetDamageeEntity().getEntityId() != getEntity().getEntityId()) + { + return; + } + + DamageCause cause = event.GetCause(); + + if (cause == DamageCause.FALL) + { + event.SetCancelled("Boss Invulnerability"); + } + } + + @EventHandler + public void buffDamage(CustomDamageEvent event) + { + if (event.GetDamagerEntity(false) == null) + { + return; + } + if (event.GetDamagerEntity(false).getEntityId() == getEntity().getEntityId() && event.GetCause() == DamageCause.ENTITY_ATTACK) + { + event.AddMod("Mage Attack", 7 - event.GetDamage()); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void ally(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) + { + location.getWorld().dropItem(location.clone().add(0, 1, 0), new ItemStack(Material.EMERALD, UtilMath.rRange(10, 20))); + location.getWorld().dropItem(location.clone().add(0, 1, 0), new ItemStack(UtilMath.randomElement(new Material[] {Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS}))); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/BlazeMinion.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/BlazeMinion.java new file mode 100644 index 00000000..0d8f9a19 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/BlazeMinion.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import org.bukkit.Location; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class BlazeMinion extends RaidCreature +{ + private RaidChallenge _challenge; + + public BlazeMinion(RaidChallenge challenge, Location spawnLocation) + { + super(challenge.getRaid(), spawnLocation, "Blaze Minion", true, 20, 500, true, Blaze.class); + + _challenge = challenge; + spawnEntity(); + } + + @Override + protected void spawnCustom() {} + + @Override + public void dieCustom() {} + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/Cataclysm.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/Cataclysm.java new file mode 100644 index 00000000..1a46b6b3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/Cataclysm.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; + +public abstract class Cataclysm implements Listener +{ + protected ChallengeSix Challenge; + protected Magmus Magmus; + + public Cataclysm(ChallengeSix challenge, Magmus magmus) + { + Challenge = challenge; + Magmus = magmus; + + challenge.getRaid().getPlayers().forEach(player -> + { + UtilPlayer.message(player, F.main(challenge.getRaid().getName() + " Raid", getAnnouncement())); + UtilTextMiddle.display("", getAnnouncement(), player); + }); + onStart(); + UtilServer.RegisterEvents(this); + } + + protected abstract String getAnnouncement(); + + protected abstract void onStart(); + + protected abstract void onEnd(); + + protected abstract void tick(); + + protected void end() + { + onEnd(); + HandlerList.unregisterAll(this); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.TICK) + { + if (Challenge.isComplete()) + { + end(); + } + else + { + tick(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/HeatingUp.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/HeatingUp.java new file mode 100644 index 00000000..8fb52f8c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/HeatingUp.java @@ -0,0 +1,76 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; + +public class HeatingUp extends Cataclysm +{ + private Location _center; + private int _ticks; + + public HeatingUp(ChallengeSix challenge, Magmus magmus) + { + super(challenge, magmus); + } + + @Override + protected String getAnnouncement() + { + return "The room is heating up! Quickly, head to a safe location!"; + } + + @SuppressWarnings("deprecation") + @Override + protected void onStart() + { + Magmus.HeatingRoom = true; + _center = Challenge.getRaid().getWorldData().getCustomLocs("C_SIX_C1S").get(0); + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + _center.getBlock().getRelative(x, -1, z).setTypeIdAndData(Material.STAINED_GLASS.getId(), DyeColor.GREEN.getWoolData(), true); + } + } + } + + @Override + protected void onEnd() + { + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + _center.getBlock().getRelative(x, -1, z).setType(Material.STONE); + } + } + Magmus.HeatingRoom = false; + } + + @Override + protected void tick() + { + _ticks++; + if (_ticks > (20 * 10) && _ticks <= (20 * 30)) + { + for (Player player : Challenge.getRaid().getPlayers()) + { + if (UtilMath.offset(player.getLocation(), _center) > 1) + { + player.setFireTicks(1); + Challenge.getRaid().getDamageManager().NewDamageEvent(player, Magmus.getEntity(), null, DamageCause.FIRE, 1, false, true, true, Magmus.getEntity().getName(), "Heat Room"); + } + } + } + if (_ticks > (20 * 33)) + { + end(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/InfernalMinions.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/InfernalMinions.java new file mode 100644 index 00000000..4255bc09 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/InfernalMinions.java @@ -0,0 +1,45 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import org.bukkit.Location; + +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight; + +public class InfernalMinions extends Cataclysm +{ + public InfernalMinions(ChallengeSix challenge, Magmus magmus) + { + super(challenge, magmus); + } + + @Override + protected String getAnnouncement() + { + return "Infernal minions have flocked to Magmus' aid!"; + } + + @Override + protected void onStart() + { + for (int i = 0; i < 20; i++) + { + Location loc = UtilMath.randomElement(Magmus.getChallenge().getRaid().getPlayers()).getLocation(); + if (UtilMath.r(2) == 1) + { + Challenge.getRaid().registerCreature(new UndeadKnight(Challenge, loc)); + } + else + { + Challenge.getRaid().registerCreature(new BlazeMinion(Challenge, loc)); + } + } + end(); + } + + @Override + protected void onEnd() {} + + @Override + protected void tick() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/Magmus.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/Magmus.java new file mode 100644 index 00000000..daae379f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/Magmus.java @@ -0,0 +1,120 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilEnt; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class Magmus extends RaidCreature +{ + private ChallengeSix _challenge; + protected List> Abilities = new ArrayList<>(); + + protected boolean TeleportBackASAP = true; + protected boolean HeatingRoom = false; + + public Magmus(ChallengeSix challenge, Location location) + { + super(challenge.getRaid(), location, "Gatekeeper Magmus", true, 2000, 500, true, MagmaCube.class); + + _challenge = challenge; + spawnEntity(); + Abilities.add(new MagmusCataclysm(this)); + Abilities.add(new MagmusSmash(this)); + Abilities.add(new MagmusMeteor(this)); + Abilities.add(new MagmusEat(this)); + } + + protected ChallengeSix getChallenge() + { + return _challenge; + } + + @Override + protected void spawnCustom() + { + UtilEnt.vegetate(getEntity()); + getEntity().setSize(17); + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + Abilities.forEach(ability -> + { + HandlerList.unregisterAll(ability); + }); + Abilities.clear(); + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + if (TeleportBackASAP) + { + getEntity().teleport(getSpawnLocation()); + } + + Abilities.forEach(BossPassive::tick); + } + + @EventHandler + public void onMagmusDamage(CustomDamageEvent event) + { + if (event.GetDamagerEntity(false) == null) + { + return; + } + if (event.GetDamagerEntity(false).getEntityId() == getEntity().getEntityId() && (event.GetCause() != DamageCause.FIRE && event.GetCause() != DamageCause.CUSTOM && event.GetCause() != DamageCause.PROJECTILE)) + { + event.SetCancelled("Wrong Attack Type Magmus"); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusCataclysm.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusCataclysm.java new file mode 100644 index 00000000..da212031 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusCataclysm.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.entity.MagmaCube; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; + +public class MagmusCataclysm extends BossPassive +{ + private long _lastUse; + private List> _cataclysms = new ArrayList<>(); + + public MagmusCataclysm(Magmus creature) + { + super(creature); + _lastUse = System.currentTimeMillis() - (getCooldown() * 1000); + _cataclysms.add(HeatingUp.class); + _cataclysms.add(InfernalMinions.class); + _cataclysms.add(UndeadAlly.class); + } + + @Override + public int getCooldown() + { + return 23; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().HeatingRoom) + { + return; + } + if (UtilTime.elapsed(_lastUse, getCooldown() * 1000)) + { + _lastUse = System.currentTimeMillis(); + if (!_cataclysms.isEmpty()) + { + try + { + UtilMath.randomElement(_cataclysms).getConstructor(ChallengeSix.class, Magmus.class).newInstance(getBoss().getChallenge(), getBoss()); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) + { + e.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusEat.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusEat.java new file mode 100644 index 00000000..eb06cd34 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusEat.java @@ -0,0 +1,94 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class MagmusEat extends BossPassive +{ + private long _lastUse; + private Player _eating; + private int _ticks; + + public MagmusEat(Magmus creature) + { + super(creature); + _lastUse = System.currentTimeMillis(); + } + + private void spit() + { + double offset = UtilMath.offset(_eating, getEntity()); + //Velocity + UtilAction.velocity(_eating, + UtilAlg.getTrajectory2d(getLocation().toVector(), _eating.getLocation().toVector()), + 2 + 2 * offset, true, 0, 1.2 + 1.0 * offset, 3, true); + + getBoss().getEvent().getCondition().Factory().Falling("Spit Out", _eating, getEntity(), 10, false, true); + + _lastUse = System.currentTimeMillis(); + _eating = null; + _ticks = -1; + } + + private void eat() + { + if (_ticks < 20 * 10 && !getBoss().HeatingRoom) + { + _eating.setFireTicks(40); + _eating.teleport(getEntity()); + } + else + { + spit(); + } + _ticks++; + } + + private void initialEat(Player target) + { + _eating = target; + _ticks = 0; + getBoss().getEvent().getCondition().Factory().Silence("Eat", _eating, getEntity(), 10, true, true); + } + + @Override + public int getCooldown() + { + return 15; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().HeatingRoom) + { + return; + } + if (_eating != null) + { + eat(); + return; + } + if (UtilTime.elapsed(_lastUse, getCooldown() * 1000)) + { + Player target = UtilPlayer.getClosest(getLocation(), 7); + if (target != null) + { + initialEat(target); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusMeteor.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusMeteor.java new file mode 100644 index 00000000..e63e49d0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusMeteor.java @@ -0,0 +1,121 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLargeFireball; +import org.bukkit.entity.LargeFireball; +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ProjectileHitEvent; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import net.minecraft.server.v1_8_R3.EntityLargeFireball; + +public class MagmusMeteor extends BossPassive +{ + private long _lastUse; + private List _shot = new ArrayList<>(); + + public MagmusMeteor(Magmus creature) + { + super(creature); + _lastUse = System.currentTimeMillis(); + } + + private void newBall() + { + if (getBoss().HeatingRoom) + { + return; + } + Player target = UtilMath.randomElement(getBoss().getChallenge().getRaid().getPlayers()); + LargeFireball ball = target.getWorld().spawn(target.getLocation().add(2 * Math.random(), 10 + Math.random() * 16, 2 * Math.random()), LargeFireball.class); + + EntityLargeFireball eFireball = ((CraftLargeFireball) ball).getHandle(); + eFireball.dirX = (Math.random()-0.5)*0.02; + eFireball.dirY = -0.2 - 0.05 * Math.random(); + eFireball.dirZ = (Math.random()-0.5)*0.02; + + ball.setShooter(getEntity()); + ball.setYield(0f); + ball.setBounce(false); + ball.setIsIncendiary(false); + _shot.add(ball); + } + + @Override + public int getCooldown() + { + return 30; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().HeatingRoom) + { + return; + } + if (UtilTime.elapsed(_lastUse, getCooldown() * 1000)) + { + _lastUse = System.currentTimeMillis(); + for (int i = 0; i < 20; i++) + { + newBall(); + } + } + } + + @EventHandler + public void onExplode(EntityExplodeEvent event) + { + if (event.getEntity() instanceof LargeFireball) + { + LargeFireball ball = (LargeFireball) event.getEntity(); + if (ball.getShooter() instanceof MagmaCube && ((MagmaCube)ball.getShooter()).getEntityId() == getEntity().getEntityId()) + { + event.blockList().clear(); + return; + } + } + } + + @EventHandler + public void onBallHit(ProjectileHitEvent event) + { + if (event.getEntity() instanceof LargeFireball) + { + LargeFireball ball = (LargeFireball) event.getEntity(); + if (_shot.contains(ball)) + { + _shot.remove(ball); + UtilParticle.PlayParticle(ParticleType.EXPLODE, ball.getLocation(), null, 0, 2, ViewDist.MAX, UtilServer.getPlayers()); + ball.getWorld().playSound(ball.getLocation(), Sound.EXPLODE, 10, 0); + Player hit = UtilPlayer.getClosest(ball.getLocation(), 3); + if (hit != null) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), ball, DamageCause.PROJECTILE, 4, true, true, false, getEntity().getName(), "Meteor Shower"); + } + ball.remove(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusSmash.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusSmash.java new file mode 100644 index 00000000..62f980cb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/MagmusSmash.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import java.util.Map; + +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class MagmusSmash extends BossPassive +{ + private long _lastUse; + + public MagmusSmash(Magmus creature) + { + super(creature); + _lastUse = System.currentTimeMillis(); + } + + private void slam() + { + //Action + Map targets = UtilPlayer.getInRadius(getLocation(), 5.5d + 0.5 * 5); + getBoss().TeleportBackASAP = false; + getEntity().setVelocity(new Vector(0, 5, 0)); + UtilServer.runSyncLater(() -> getBoss().TeleportBackASAP = true, 3 * 20); + for (Player player : targets.keySet()) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, + DamageCause.CUSTOM, 6 * targets.get(player) + 0.5, false, true, false, + getEntity().getName(), "Smash"); + + //Velocity + UtilAction.velocity(player, + UtilAlg.getTrajectory2d(getLocation().toVector(), player.getLocation().toVector()), + 2 + 2 * targets.get(player), true, 0, 1.2 + 1.0 * targets.get(player), 3, true); + + //Condition + getBoss().getEvent().getCondition().Factory().Falling("Smash", player, getEntity(), 10, false, true); + } + } + + @Override + public int getCooldown() + { + return 10; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().HeatingRoom) + { + return; + } + if (UtilTime.elapsed(_lastUse, getCooldown() * 1000)) + { + _lastUse = System.currentTimeMillis(); + slam(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/UndeadAlly.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/UndeadAlly.java new file mode 100644 index 00000000..06730bf2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/magma/UndeadAlly.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.magma; + +import mineplex.game.clans.clans.worldevent.raid.wither.challenge.six.ChallengeSix; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadMage; + +public class UndeadAlly extends Cataclysm +{ + public UndeadAlly(ChallengeSix challenge, Magmus magmus) + { + super(challenge, magmus); + } + + @Override + protected String getAnnouncement() + { + return "Magmus has summoned an undead ally!"; + } + + @Override + protected void onStart() + { + Challenge.getRaid().registerCreature(new UndeadMage(Challenge, Challenge.getRaid().getWorldData().getCustomLocs("C_SIX_C3S").get(0), false, null, null)); + end(); + } + + @Override + protected void onEnd() {} + + @Override + protected void tick() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/BlackHole.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/BlackHole.java new file mode 100644 index 00000000..2465a56a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/BlackHole.java @@ -0,0 +1,129 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; + +public class BlackHole extends BossPassive +{ + private static final double RANGE = 15; + private long _lastUsed; + private int _chargeTicks; + + public BlackHole(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + _chargeTicks = -1; + } + + private void pull() + { + for (Player entity : UtilPlayer.getInRadius(getLocation(), RANGE).keySet()) + { + UtilAction.velocity(entity, UtilAlg.getTrajectory(entity, getEntity()), 0.3, false, 0, 0, 1, true); + } + for (int i = 0; i < 6; i++) + { + Vector random = new Vector(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2); + + Location origin = getLocation().add(0, 1.3, 0); + origin.add(getLocation().getDirection().multiply(10)); + origin.add(random); + + Vector vel = UtilAlg.getTrajectory(origin, getLocation().add(0, 1.3, 0)); + vel.multiply(7); + + UtilParticle.PlayParticle(ParticleType.MAGIC_CRIT, + origin, + (float)vel.getX(), + (float)vel.getY(), + (float)vel.getZ(), + 1, 0, ViewDist.LONG, UtilServer.getPlayers()); + } + } + + private void throwUp() + { + Map near = UtilPlayer.getInRadius(getLocation(), RANGE); + for (Entry thr : near.entrySet()) + { + Vector vel = new Vector(0, Math.min(7.5, Math.max(5 / thr.getValue(), 4)), 0); + thr.getKey().setVelocity(vel); + } + } + + @Override + public int getCooldown() + { + return 60; + } + + @Override + public boolean isProgressing() + { + return _chargeTicks != -1; + } + + @Override + public void tick() + { + if (_chargeTicks != -1) + { + _chargeTicks++; + if (_chargeTicks >= (20 * 5)) + { + _lastUsed = System.currentTimeMillis(); + _chargeTicks = -1; + throwUp(); + } + else + { + pull(); + } + return; + } + if (getBoss().getHealthPercent() <= 0.25) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _chargeTicks = 0; + ((WitherRaid)getBoss().getEvent()).getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getBoss().getEvent().getName() + " Raid", "He's charging up Decay! Run away!"))); + } + } + } + } + + @EventHandler + public void onKick(PlayerKickEvent event) + { + if (_chargeTicks != -1 && getBoss().getChallenge().getRaid().getPlayers().contains(event.getPlayer())) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/CharlesSkulls.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/CharlesSkulls.java new file mode 100644 index 00000000..88e88a8c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/CharlesSkulls.java @@ -0,0 +1,191 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; + +public class CharlesSkulls extends BossAbility +{ + private long _lastUnguided; + private long _lastGuided; + private long _lastBombard; + private Map _guidedSkulls; + + public CharlesSkulls(CharlesWitherton creature) + { + super(creature); + + _guidedSkulls = new HashMap<>(); + _lastUnguided = System.currentTimeMillis(); + _lastGuided = System.currentTimeMillis(); + _lastBombard = -1; + } + + @Override + public void tick() + { + if (getBoss().getHealthPercent() <= 0.75) + { + if (_lastBombard == -1) + { + _lastBombard = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastBombard, 25000)) + { + Player target = UtilPlayer.getClosest(getLocation()); + if (target != null) + { + _lastBombard = System.currentTimeMillis(); + UtilEnt.LookAt(getEntity(), target.getEyeLocation()); + for (int i = 0; i < 15; i++) + { + UtilEnt.addFlag(getEntity().launchProjectile(WitherSkull.class), "BOMBARD"); + } + return; + } + } + } + } + if (UtilTime.elapsed(_lastUnguided, 10000)) + { + Player target = UtilPlayer.getClosest(getLocation()); + if (target != null) + { + _lastUnguided = System.currentTimeMillis(); + UtilEnt.LookAt(getEntity(), target.getEyeLocation()); + getEntity().launchProjectile(WitherSkull.class); + return; + } + } + if (UtilTime.elapsed(_lastGuided, 5000)) + { + Player target = UtilPlayer.getClosest(getLocation()); + if (target != null) + { + _lastGuided = System.currentTimeMillis(); + UtilEnt.LookAt(getEntity(), target.getEyeLocation()); + WitherSkull skull = getEntity().launchProjectile(WitherSkull.class); + UtilEnt.addFlag(skull, "GUIDED"); + _guidedSkulls.put(skull, target); + } + } + + Iterator> iterator = _guidedSkulls.entrySet().iterator(); + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + if (!entry.getKey().isValid() || entry.getKey().isDead()) + { + iterator.remove(); + continue; + } + Vector velocity = UtilAlg.getTrajectory(entry.getKey(), entry.getValue()); + entry.getKey().setDirection(velocity); + entry.getKey().setVelocity(velocity.multiply(0.6)); + } + } + + @EventHandler + public void onExplode(EntityExplodeEvent event) + { + if (event.getEntity().getEntityId() == getEntity().getEntityId()) + { + event.blockList().clear(); + return; + } + if (event.getEntity() instanceof WitherSkull) + { + WitherSkull skull = (WitherSkull) event.getEntity(); + if (skull.getShooter() instanceof Wither && ((Wither)skull.getShooter()).getEntityId() == getEntity().getEntityId()) + { + event.blockList().clear(); + return; + } + } + } + + @EventHandler + public void onSkullHit(ProjectileHitEvent event) + { + if (event.getEntity() instanceof WitherSkull) + { + WitherSkull skull = (WitherSkull) event.getEntity(); + if (skull.getShooter() instanceof Wither && ((Wither)skull.getShooter()).getEntityId() == getEntity().getEntityId()) + { + UtilParticle.PlayParticle(ParticleType.EXPLODE, skull.getLocation(), null, 0, 2, ViewDist.MAX, UtilServer.getPlayers()); + skull.getWorld().playSound(skull.getLocation(), Sound.EXPLODE, 10, 0); + if (UtilEnt.hasFlag(skull, "GUIDED")) + { + Player hit = UtilPlayer.getClosest(skull.getLocation(), 0.5); + if (hit != null) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), skull, DamageCause.PROJECTILE, 2, true, true, false, getEntity().getName(), "Guided Skull"); + } + } + else if (UtilEnt.hasFlag(skull, "BOMBARD")) + { + Player hit = UtilPlayer.getClosest(skull.getLocation(), 0.5); + if (hit != null) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), skull, DamageCause.PROJECTILE, 2, true, true, false, getEntity().getName(), "Bombardment"); + } + } + else + { + Player hit = UtilPlayer.getClosest(skull.getLocation(), 0.5); + if (hit != null) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), skull, DamageCause.PROJECTILE, 4, true, true, false, getEntity().getName(), "Wither Skull"); + getBoss().getEvent().getCondition().Factory().Wither("Wither Skull", hit, getEntity(), 3, 0, false, true, false); + } + } + skull.remove(); + } + } + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return false; + } + + @Override + public void setFinished() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/CharlesWitherton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/CharlesWitherton.java new file mode 100644 index 00000000..225ece46 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/CharlesWitherton.java @@ -0,0 +1,203 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.server.v1_8_R3.Entity; +import net.minecraft.server.v1_8_R3.EntityHuman; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.EntityWither; +import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; +import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; +import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; +import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; +import net.minecraft.server.v1_8_R3.PathfinderGoalRandomStroll; + +import org.bukkit.Location; +import org.bukkit.craftbukkit.libs.com.google.common.base.Predicate; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftWither; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.ai.PathfinderGoalCustomFloat; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class CharlesWitherton extends RaidCreature +{ + private RaidChallenge _challenge; + private CharlesSkulls _passive; + private List> _abilities = new ArrayList<>(); + + public boolean Flying = false; + + public CharlesWitherton(RaidChallenge challenge, Location location) + { + super(challenge.getRaid(), location, "Charles Witherton", true, 5000, 15000, true, Wither.class); + + _challenge = challenge; + spawnEntity(); + _passive = new CharlesSkulls(this); + _abilities.add(new LifeSap(this)); + _abilities.add(new Flight(this)); + _abilities.add(new Decay(this)); + _abilities.add(new WitherWave(this)); + _abilities.add(new SummonUndead(this)); + _abilities.add(new SummonCorpse(this)); + _abilities.add(new BlackHole(this)); + _abilities.add(new SummonMinions(this)); + } + + protected RaidChallenge getChallenge() + { + return _challenge; + } + + protected List getCustomLocs(String id) + { + return _challenge.getRaid().getWorldData().getCustomLocs(id); + } + + @Override + protected void spawnCustom() + { + UtilEnt.vegetate(getEntity()); + CraftWither cw = (CraftWither)getEntity(); + EntityWither wither = cw.getHandle(); + wither.setVegetated(false); + wither.goalSelector.a(0, new PathfinderGoalCustomFloat(this, wither)); + wither.goalSelector.a(5, new PathfinderGoalRandomStroll(wither, 1.0D)); + wither.goalSelector.a(6, new PathfinderGoalLookAtPlayer(wither, EntityHuman.class, 8.0F)); + wither.goalSelector.a(7, new PathfinderGoalRandomLookaround(wither)); + wither.targetSelector.a(1, new PathfinderGoalHurtByTarget(wither, false, new Class[0])); + wither.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(wither, EntityInsentient.class, 0, false, false, new Predicate() + { + public boolean a(Entity entity) + { + return entity instanceof EntityHuman; + } + + public boolean apply(Entity entity) + { + return this.a(entity); + } + })); + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + for (BossPassive ability : _abilities) + { + HandlerList.unregisterAll(ability); + } + _abilities.clear(); + _passive.setFinished(); + HandlerList.unregisterAll(_passive); + _passive = null; + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + for (Block b : UtilBlock.getBlocksInRadius(getEntity().getLocation(), 4)) + { + if (b.getType() == Material.ICE) + { + if (ClansManager.getInstance().getBlockRestore().contains(b)) + { + ClansManager.getInstance().getBlockRestore().restore(b); + } + else + { + b.setType(Material.AIR); + } + } + } + + _passive.tick(); + _abilities.forEach(BossPassive::tick); + + if (Flying) + { + getEntity().setHealth(500); + } + else + { + getEntity().setHealth(100); + } + } + + @EventHandler + public void handleBlockChange(EntityChangeBlockEvent event) + { + if (event.getEntity().getEntityId() == getEntity().getEntityId()) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onLaunch(ProjectileLaunchEvent event) + { + if (event.getEntity() instanceof WitherSkull && event.getEntity().getShooter() instanceof Wither) + { + if (((Wither)event.getEntity().getShooter()).getEntityId() == getEntity().getEntityId()) + { + if (((WitherSkull)event.getEntity()).isCharged()) + { + event.setCancelled(true); + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/Decay.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/Decay.java new file mode 100644 index 00000000..b7271831 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/Decay.java @@ -0,0 +1,79 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; + +public class Decay extends BossPassive +{ + private static final double RANGE = 28; + private long _lastUsed; + private int _chargeTicks; + + public Decay(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + _chargeTicks = -1; + } + + @Override + public int getCooldown() + { + return 300; + } + + @Override + public boolean isProgressing() + { + return _chargeTicks != -1; + } + + @Override + public void tick() + { + if (_chargeTicks != -1) + { + _chargeTicks++; + if (_chargeTicks >= (20 * 5)) + { + _lastUsed = System.currentTimeMillis(); + _chargeTicks = -1; + for (Player player : UtilPlayer.getInRadius(getLocation(), RANGE).keySet()) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.WITHER, 1000, false, true, true, getEntity().getName(), "Decay"); + } + } + else + { + getEntity().teleport(getBoss().getCustomLocs("C_SEVEN_RWC").get(0)); + for (Location loc : UtilShapes.getSphereBlocks(getEntity().getEyeLocation(), 2, 2, true)) + { + UtilParticle.playColoredParticleToAll(Color.RED, ParticleType.RED_DUST, loc, 2, ViewDist.MAX); + UtilParticle.playColoredParticleToAll(Color.BLACK, ParticleType.RED_DUST, loc, 2, ViewDist.MAX); + } + } + return; + } + if (getBoss().getHealthPercent() <= 0.5) + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _chargeTicks = 0; + ((WitherRaid)getBoss().getEvent()).getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getBoss().getEvent().getName() + " Raid", "He's charging up Decay! Run away!"))); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/Flight.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/Flight.java new file mode 100644 index 00000000..bb1cafc2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/Flight.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.entity.Wither; + +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class Flight extends BossPassive +{ + private long _lastUsed; + private int _flyingTicks; + + public Flight(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + _flyingTicks = -1; + } + + @Override + public int getCooldown() + { + return 200; + } + + @Override + public boolean isProgressing() + { + return _flyingTicks != -1; + } + + @Override + public void tick() + { + if (_flyingTicks != -1) + { + _flyingTicks++; + if (_flyingTicks >= (20 * 20)) + { + _lastUsed = System.currentTimeMillis(); + _flyingTicks = -1; + getBoss().Flying = false; + } + return; + } + if (getBoss().getHealthPercent() <= 0.75) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + getBoss().Flying = true; + _flyingTicks = 0; + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/LifeSap.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/LifeSap.java new file mode 100644 index 00000000..5afeb2e8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/LifeSap.java @@ -0,0 +1,116 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class LifeSap extends BossPassive +{ + private static final double RANGE = 20; + private long _lastUsed; + private int _chargeTicks; + + public LifeSap(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + _chargeTicks = -1; + } + + private void shootBeam(Player target) + { + double curRange = 0; + boolean canHit = true; + + while (curRange <= RANGE) + { + Location newTarget = getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity(), target).multiply(curRange)); + + if (!UtilBlock.airFoliage(newTarget.getBlock())) + { + canHit = false; + break; + } + if (UtilMath.offset(newTarget, target.getLocation()) <= 0.9) + { + break; + } + + curRange += 0.2; + + UtilParticle.playColoredParticleToAll(Color.RED, ParticleType.RED_DUST, newTarget, 5, ViewDist.MAX); + } + + if (canHit) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 2.5, true, true, false, getEntity().getName(), "Mystical Energy"); + getBoss().setHealth(getBoss().getHealth() + 200); + } + } + + @Override + public int getCooldown() + { + return 60; + } + + @Override + public boolean isProgressing() + { + return _chargeTicks != -1; + } + + @Override + public void tick() + { + if (_chargeTicks != -1) + { + _chargeTicks++; + if (_chargeTicks >= (20 * 4)) + { + _lastUsed = System.currentTimeMillis(); + _chargeTicks = -1; + Player target = UtilPlayer.getClosest(getLocation(), RANGE); + if (target != null) + { + shootBeam(target); + } + } + else + { + for (Location loc : UtilShapes.getCircle(getEntity().getEyeLocation(), true, 1.5)) + { + UtilParticle.playColoredParticleToAll(Color.RED, ParticleType.RED_DUST, loc, 2, ViewDist.MAX); + } + } + return; + } + if (getBoss().getHealthPercent() <= 0.75) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _chargeTicks = 0; + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/MiniCharles.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/MiniCharles.java new file mode 100644 index 00000000..8326fb4a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/MiniCharles.java @@ -0,0 +1,182 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import net.minecraft.server.v1_8_R3.Entity; +import net.minecraft.server.v1_8_R3.EntityHuman; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.EntityWither; +import net.minecraft.server.v1_8_R3.PathfinderGoalHurtByTarget; +import net.minecraft.server.v1_8_R3.PathfinderGoalLookAtPlayer; +import net.minecraft.server.v1_8_R3.PathfinderGoalNearestAttackableTarget; +import net.minecraft.server.v1_8_R3.PathfinderGoalRandomLookaround; +import net.minecraft.server.v1_8_R3.PathfinderGoalRandomStroll; + +import org.bukkit.Location; +import org.bukkit.craftbukkit.libs.com.google.common.base.Predicate; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftWither; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.raid.RaidChallenge; +import mineplex.game.clans.clans.worldevent.raid.RaidCreature; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.ai.PathfinderGoalCustomFloat; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class MiniCharles extends RaidCreature +{ + private CharlesWitherton _charles; + private RaidChallenge _challenge; + private MiniCharlesSkulls _passive; + private int _liveTicks; + + protected boolean Flying = false; + + public MiniCharles(CharlesWitherton charles, Location location) + { + super(charles.getChallenge().getRaid(), location, "Charles' Minion", true, 50, 15000, true, Wither.class); + + _charles = charles; + _challenge = charles.getChallenge(); + spawnEntity(); + _passive = new MiniCharlesSkulls(this); + } + + @Override + protected void spawnCustom() + { + UtilEnt.vegetate(getEntity()); + EntityWither wither = ((CraftWither)getEntity()).getHandle(); + wither.setVegetated(false); + wither.goalSelector.a(0, new PathfinderGoalCustomFloat(_charles, wither)); + wither.goalSelector.a(5, new PathfinderGoalRandomStroll(wither, 1.0D)); + wither.goalSelector.a(6, new PathfinderGoalLookAtPlayer(wither, EntityHuman.class, 8.0F)); + wither.goalSelector.a(7, new PathfinderGoalRandomLookaround(wither)); + wither.targetSelector.a(1, new PathfinderGoalHurtByTarget(wither, false, new Class[0])); + wither.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(wither, EntityInsentient.class, 0, false, false, new Predicate() + { + public boolean a(Entity entity) + { + return entity instanceof EntityHuman; + } + + public boolean apply(Entity entity) + { + return this.a(entity); + } + })); + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + _passive.setFinished(); + HandlerList.unregisterAll(_passive); + _passive = null; + } + + @EventHandler + public void onTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_challenge.isComplete()) + { + remove(); + return; + } + + for (Block b : UtilBlock.getBlocksInRadius(getEntity().getLocation(), 4)) + { + if (b.getType() == Material.ICE) + { + if (ClansManager.getInstance().getBlockRestore().contains(b)) + { + ClansManager.getInstance().getBlockRestore().restore(b); + } + else + { + b.setType(Material.AIR); + } + } + } + + _passive.tick(); + + _liveTicks++; + if (_liveTicks > (20 * 15)) + { + remove(); + } + + if (Flying) + { + getEntity().setHealth(500); + } + else + { + getEntity().setHealth(100); + } + } + + @EventHandler + public void handleBlockChange(EntityChangeBlockEvent event) + { + if (event.getEntity().getEntityId() == getEntity().getEntityId()) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onLaunch(ProjectileLaunchEvent event) + { + if (event.getEntity() instanceof WitherSkull && event.getEntity().getShooter() instanceof Wither) + { + if (((Wither)event.getEntity().getShooter()).getEntityId() == getEntity().getEntityId()) + { + if (((WitherSkull)event.getEntity()).isCharged()) + { + event.setCancelled(true); + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void allyDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId()) + { + LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE); + if (damager != null && !(damager instanceof Player)) + { + event.SetCancelled("Allied Damage"); + } + } + } + + @Override + public void handleDeath(Location location) {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/MiniCharlesSkulls.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/MiniCharlesSkulls.java new file mode 100644 index 00000000..135decf8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/MiniCharlesSkulls.java @@ -0,0 +1,117 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ProjectileHitEvent; + +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossAbility; + +public class MiniCharlesSkulls extends BossAbility +{ + private long _lastUnguided; + private List _shot = new ArrayList<>(); + + public MiniCharlesSkulls(MiniCharles creature) + { + super(creature); + + _lastUnguided = System.currentTimeMillis(); + } + + @Override + public void tick() + { + if (UtilTime.elapsed(_lastUnguided, 10000)) + { + Player target = UtilPlayer.getClosest(getLocation()); + if (target != null) + { + _lastUnguided = System.currentTimeMillis(); + UtilEnt.LookAt(getEntity(), target.getEyeLocation()); + _shot.add(getEntity().launchProjectile(WitherSkull.class)); + return; + } + } + } + + @EventHandler + public void onExplode(EntityExplodeEvent event) + { + if (event.getEntity().getEntityId() == getEntity().getEntityId()) + { + event.blockList().clear(); + return; + } + if (event.getEntity() instanceof WitherSkull) + { + WitherSkull skull = (WitherSkull) event.getEntity(); + if (skull.getShooter() instanceof Wither && ((Wither)skull.getShooter()).getEntityId() == getEntity().getEntityId()) + { + event.blockList().clear(); + return; + } + } + } + + @EventHandler + public void onSkullHit(ProjectileHitEvent event) + { + if (event.getEntity() instanceof WitherSkull) + { + WitherSkull skull = (WitherSkull) event.getEntity(); + if (skull.getShooter() instanceof Wither && ((Wither)skull.getShooter()).getEntityId() == getEntity().getEntityId()) + { + _shot.remove(skull); + UtilParticle.PlayParticle(ParticleType.EXPLODE, skull.getLocation(), null, 0, 2, ViewDist.MAX, UtilServer.getPlayers()); + skull.getWorld().playSound(skull.getLocation(), Sound.EXPLODE, 10, 0); + Player hit = UtilPlayer.getClosest(skull.getLocation(), 0.5); + if (hit != null) + { + getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), skull, DamageCause.PROJECTILE, 4, true, true, false, getEntity().getName(), "Wither Skull"); + getBoss().getEvent().getCondition().Factory().Wither("Wither Skull", hit, getEntity(), 3, 0, false, true, false); + } + skull.remove(); + } + } + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public boolean inProgress() + { + return false; + } + + @Override + public boolean hasFinished() + { + return false; + } + + @Override + public void setFinished() + { + _shot.forEach(WitherSkull::remove); + _shot.clear(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonCorpse.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonCorpse.java new file mode 100644 index 00000000..492b8b71 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonCorpse.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.entity.Wither; + +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.corpse.ReanimatedCorpse; + +public class SummonCorpse extends BossPassive +{ + private long _lastUsed; + + public SummonCorpse(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + } + + @Override + public int getCooldown() + { + return 30; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().getHealthPercent() <= 0.50) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _lastUsed = System.currentTimeMillis(); + for (int i = 0; i < 6; i++) + { + getBoss().getEvent().registerCreature(new ReanimatedCorpse(getBoss().getChallenge(), getLocation())); + } + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonMinions.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonMinions.java new file mode 100644 index 00000000..7ea48dcd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonMinions.java @@ -0,0 +1,52 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.entity.Wither; + +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; + +public class SummonMinions extends BossPassive +{ + private long _lastUsed; + + public SummonMinions(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + } + + @Override + public int getCooldown() + { + return 60; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().getHealthPercent() <= 0.25) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _lastUsed = System.currentTimeMillis(); + for (int i = 0; i < 2; i++) + { + getBoss().getEvent().registerCreature(new MiniCharles(getBoss(), getLocation())); + } + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonUndead.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonUndead.java new file mode 100644 index 00000000..0862c84d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/SummonUndead.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.entity.Wither; + +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight; + +public class SummonUndead extends BossPassive +{ + private long _lastUsed; + + public SummonUndead(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + } + + @Override + public int getCooldown() + { + return 60; + } + + @Override + public boolean isProgressing() + { + return false; + } + + @Override + public void tick() + { + if (getBoss().getHealthPercent() <= 0.50) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _lastUsed = System.currentTimeMillis(); + for (int i = 0; i < 6; i++) + { + getBoss().getEvent().registerCreature(new UndeadKnight(getBoss().getChallenge(), getLocation())); + } + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/WitherWave.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/WitherWave.java new file mode 100644 index 00000000..ae7fea54 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/WitherWave.java @@ -0,0 +1,91 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wither; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.api.BossPassive; +import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; + +public class WitherWave extends BossPassive +{ + private static final double RANGE = 10; + private long _lastUsed; + private int _chargeTicks; + + public WitherWave(CharlesWitherton creature) + { + super(creature); + _lastUsed = -1; + _chargeTicks = -1; + } + + @Override + public int getCooldown() + { + return 60; + } + + @Override + public boolean isProgressing() + { + return _chargeTicks != -1; + } + + @Override + public void tick() + { + if (_chargeTicks != -1) + { + _chargeTicks++; + if (_chargeTicks >= (20 * 5)) + { + for (Location loc : UtilShapes.getSphereBlocks(getLocation(), RANGE / 2, RANGE / 2, false)) + { + UtilParticle.playColoredParticleToAll(Color.GRAY, ParticleType.RED_DUST, loc, 2, ViewDist.MAX); + } + for (Player player : UtilPlayer.getInRadius(getLocation(), RANGE).keySet()) + { + getBoss().getEvent().getCondition().Factory().Wither("Wither Wave", player, getEntity(), 5, 1, false, true, false); + } + if (_chargeTicks >= (20 * 10)) + { + _lastUsed = System.currentTimeMillis(); + _chargeTicks = -1; + } + } + else + { + getEntity().teleport(getLocation()); + for (Location loc : UtilShapes.getSphereBlocks(getEntity().getEyeLocation(), 2, 2, true)) + { + UtilParticle.playColoredParticleToAll(Color.GRAY, ParticleType.RED_DUST, loc, 2, ViewDist.MAX); + } + } + return; + } + if (getBoss().getHealthPercent() <= 0.5) + { + if (_lastUsed == -1) + { + _lastUsed = System.currentTimeMillis(); + } + else + { + if (UtilTime.elapsed(_lastUsed, getCooldown() * 1000)) + { + _chargeTicks = 0; + ((WitherRaid)getBoss().getEvent()).getPlayers().forEach(player -> UtilPlayer.message(player, F.main(getBoss().getEvent().getName() + " Raid", "He's charging up Decay! Run away!"))); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/ai/PathfinderGoalCustomFloat.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/ai/PathfinderGoalCustomFloat.java new file mode 100644 index 00000000..227413fd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/wither/creature/wither/ai/PathfinderGoalCustomFloat.java @@ -0,0 +1,33 @@ +package mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.ai; + +import mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.CharlesWitherton; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.Navigation; +import net.minecraft.server.v1_8_R3.PathfinderGoal; + +public class PathfinderGoalCustomFloat extends PathfinderGoal +{ + private CharlesWitherton _boss; + private EntityInsentient a; + + public PathfinderGoalCustomFloat(CharlesWitherton boss, EntityInsentient ent) + { + _boss = boss; + this.a = ent; + this.a(4); + ((Navigation)ent.getNavigation()).d(true); + } + + public boolean a() + { + return _boss.Flying; + } + + public void e() + { + if (this.a.bc().nextFloat() < 0.8F) + { + this.a.getControllerJump().a(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CityChest.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CityChest.java new file mode 100644 index 00000000..00d88d28 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CityChest.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.clans.worldevent.undead; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.block.Block; + +import mineplex.game.clans.clans.ClansManager; + +public class CityChest +{ + private final boolean _enabled; + private final Block _block; + private boolean _opened; + + public CityChest(Block block, boolean enabled) + { + _block = block; + _enabled = enabled; + _opened = false; + + if (!enabled) + { + _block.setType(Material.AIR); + } + } + + public boolean isEnabled() + { + return _enabled; + } + + public boolean isOpen() + { + return _opened; + } + + @SuppressWarnings("deprecation") + public void open() + { + _block.setType(Material.AIR); + _block.getWorld().playEffect(_block.getLocation(), Effect.STEP_SOUND, Material.ENDER_CHEST.getId()); + ClansManager.getInstance().getLootManager().dropUndeadCity(_block.getLocation().add(0.5, 0, 0.5)); + _opened = true; + } + + public void revert() + { + _block.setType(Material.ENDER_CHEST); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCity.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCity.java new file mode 100644 index 00000000..5a2ea222 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCity.java @@ -0,0 +1,198 @@ +package mineplex.game.clans.clans.worldevent.undead; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.api.EventState; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.game.clans.clans.worldevent.undead.creature.UndeadArcher; +import mineplex.game.clans.clans.worldevent.undead.creature.UndeadWarrior; + +public class UndeadCity extends WorldEvent +{ + + private final int _maxChests; + private final int _maxMobs; + private final Map _chests = new HashMap<>(); + private final List _spawnSpots = new ArrayList<>(); + private long _lastSpawn; + + public UndeadCity(WorldEventManager manager) + { + super("Undead City", UndeadCityLocation.getRandomLocation().toLocation(UtilWorld.getWorld("world")), 55, true, manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getDamage(), manager.getBlockRestore(), manager.getClans().getCondition()); + + _maxChests = UndeadCityLocation.getLastLocation().getMaxChests(); + _maxMobs = UndeadCityLocation.getLastLocation().getMaxMobs(); + } + + @Override + public boolean allowsIcePrison() + { + return true; + } + + @Override + protected void customStart() + { + int addedChests = 0; + int addedMobs = 0; + double size = getEventArena().getRadius(); + + for (Block block : UtilBlock.getInBoundingBox(getCenterLocation().clone().add(size, size, size), getCenterLocation().clone().subtract(size, size, size))) + { + if (block.getType() == Material.ENDER_CHEST) + { + BlockPosition position = new BlockPosition(block); + CityChest chest = new CityChest(block, addedChests++ < _maxChests); + _chests.put(position, chest); + } + } + for (int i = 0; i < (_maxMobs + 10); i++) + { + Location loc = ClansManager.getInstance().getWorldEvent().getTerrainFinder().locateSpace(getCenterLocation(), 55, 0, 3, 0, false, true, new HashSet<>()); + if (loc == null) + { + continue; + } + _spawnSpots.add(loc); + if (addedMobs++ < _maxMobs) + { + if (ThreadLocalRandom.current().nextInt(2) == 0) + { + registerCreature(new UndeadArcher(this, loc)); + } + else + { + registerCreature(new UndeadWarrior(this, loc)); + } + } + } + + _lastSpawn = System.currentTimeMillis(); + } + + @Override + protected void customTick() + { + if (getState() != EventState.LIVE) + { + return; + } + int active = 0; + for (CityChest chest : _chests.values()) + { + if (chest.isEnabled() && !chest.isOpen()) + { + active++; + } + } + if (active < 1) + { + stop(); + return; + } + if (UtilTime.elapsed(_lastSpawn, 15000) && getCreatures().size() < Math.min(_maxMobs, _spawnSpots.size())) + { + Location loc = UtilMath.randomElement(_spawnSpots); + if (ThreadLocalRandom.current().nextInt(2) == 0) + { + registerCreature(new UndeadArcher(this, loc)); + } + else + { + registerCreature(new UndeadWarrior(this, loc)); + } + + _lastSpawn = System.currentTimeMillis(); + } + } + + @Override + public void customCleanup(boolean onDisable) + { + _chests.values().forEach(CityChest::revert); + } + + @Override + protected void customStop() + { + _chests.clear(); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onChestOpen(PlayerInteractEvent event) + { + if (UtilPlayer.isSpectator(event.getPlayer()) || event.getPlayer().getGameMode() == GameMode.CREATIVE) + { + return; + } + if (!event.hasBlock()) + { + return; + } + if (!UtilEvent.isAction(event, ActionType.ANY)) + { + return; + } + BlockPosition block = new BlockPosition(event.getClickedBlock()); + if (_chests.containsKey(block)) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You smash open an " + F.elem("Undead Chest") + "!")); + _chests.get(block).open(); + } + } + + private static class BlockPosition + { + private final int _x, _y, _z; + + public BlockPosition(Block block) + { + _x = block.getX(); + _y = block.getY(); + _z = block.getZ(); + } + + @Override + public int hashCode() + { + return Objects.hash(_x, _y, _z); + } + + @Override + public boolean equals(Object o) + { + if (o instanceof BlockPosition) + { + BlockPosition pos = (BlockPosition) o; + return pos._x == _x && pos._y == _y && pos._z == _z; + } + + return false; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCityLocation.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCityLocation.java new file mode 100644 index 00000000..f76ce232 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCityLocation.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.clans.worldevent.undead; + +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Location; +import org.bukkit.World; + +public enum UndeadCityLocation +{ + CITY(92, 68, 1181, 30, 45) + ; + + private static UndeadCityLocation _lastLocation; + private final double _x, _y, _z; + private final int _maxChests, _maxMobs; + + private UndeadCityLocation(double x, double y, double z, int maxChests, int maxMobs) + { + _x = x; + _y = y; + _z = z; + _maxChests = maxChests; + _maxMobs = maxMobs; + } + + public Location toLocation(World world) + { + return new Location(world, _x, _y, _z); + } + + public int getMaxChests() + { + return _maxChests; + } + + public int getMaxMobs() + { + return _maxMobs; + } + + public static UndeadCityLocation getRandomLocation() + { + return _lastLocation = UndeadCityLocation.values()[ThreadLocalRandom.current().nextInt(UndeadCityLocation.values().length)]; + } + + public static UndeadCityLocation getLastLocation() + { + return _lastLocation; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadArcher.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadArcher.java new file mode 100644 index 00000000..4c0fe70f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadArcher.java @@ -0,0 +1,189 @@ +package mineplex.game.clans.clans.worldevent.undead.creature; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class UndeadArcher extends EventCreature +{ + public static final int BARBED_LEVEL = 1; + + private Set _arrows = new HashSet<>(); + + public UndeadArcher(WorldEvent event, Location spawnLocation) + { + super(event, spawnLocation, "Undead Archer", true, 30, 30, true, Skeleton.class); + + spawnEntity(); + } + + @Override + protected void spawnCustom() + { + Skeleton entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setItemInHand(new ItemStack(Material.BOW)); + eq.setHelmet(new ItemStack(Material.CHAINMAIL_HELMET)); + eq.setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS)); + eq.setBoots(new ItemStack(Material.CHAINMAIL_BOOTS)); + eq.setItemInHandDropChance(0.f); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void dieCustom() + { + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_HELMET)); + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_CHESTPLATE)); + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_LEGGINGS)); + } + + if (Math.random() > 0.97) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_BOOTS)); + } + + if (Math.random() > 0.90) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.BOW)); + } + + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.ARROW, UtilMath.r(12) + 1)); + + for (int i = 0; i < UtilMath.r(5) + 1; i++) + { + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.EMERALD)); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void bowShoot(EntityShootBowEvent event) + { + if (BARBED_LEVEL == 0) + { + return; + } + + if (!(event.getProjectile() instanceof Projectile)) + { + return; + } + + _arrows.add((Projectile) event.getProjectile()); + } + + @EventHandler(priority = EventPriority.HIGH) + public void damage(CustomDamageEvent event) + { + if (event.IsCancelled()) + { + return; + } + + if (event.GetCause() != DamageCause.PROJECTILE) + { + return; + } + + Projectile projectile = event.GetProjectile(); + LivingEntity damagee = event.GetDamageeEntity(); + Player damager = event.GetDamagerPlayer(true); + + if (projectile == null) + { + return; + } + + if (damagee == null) + { + return; + } + + if (damager == null) + { + return; + } + + // Level + if (BARBED_LEVEL == 0) + { + return; + } + + Player damageePlayer = event.GetDamageePlayer(); + + if (damageePlayer != null) + { + damageePlayer.setSprinting(false); + } + + // Damage + event.AddMod(damager.getName(), "Barbed Arrows", 0, false); + + // Condition + getEvent().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true); + } + + @EventHandler + public void clean(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) return; + + for (Iterator arrowIterator = _arrows.iterator(); arrowIterator.hasNext();) + { + Projectile arrow = arrowIterator.next(); + + if (arrow.isDead() || !arrow.isValid()) arrowIterator.remove(); + } + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadWarrior.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadWarrior.java new file mode 100644 index 00000000..4884b0f9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadWarrior.java @@ -0,0 +1,115 @@ +package mineplex.game.clans.clans.worldevent.undead.creature; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.api.EventCreature; +import mineplex.game.clans.clans.worldevent.api.WorldEvent; + +public class UndeadWarrior extends EventCreature +{ + public UndeadWarrior(WorldEvent event, Location spawnLocation) + { + super(event, spawnLocation, "Undead Warrior", true, 50, 30, true, Zombie.class); + + spawnEntity(); + } + + @Override + protected void spawnCustom() + { + Zombie entity = getEntity(); + EntityEquipment eq = entity.getEquipment(); + eq.setHelmet(new ItemStack(Material.IRON_HELMET)); + eq.setChestplate(new ItemStack(Material.IRON_CHESTPLATE)); + eq.setLeggings(new ItemStack(Material.IRON_LEGGINGS)); + eq.setBoots(new ItemStack(Material.IRON_BOOTS)); + eq.setItemInHand(new ItemStack(Material.STONE_SWORD)); + eq.setHelmetDropChance(0.f); + eq.setChestplateDropChance(0.f); + eq.setLeggingsDropChance(0.f); + eq.setBootsDropChance(0.f); + eq.setItemInHandDropChance(0.f); + entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0)); + } + + @Override + public void dieCustom() + { + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.IRON_HELMET)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.IRON_CHESTPLATE)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.IRON_LEGGINGS)); + + if (Math.random() > 0.97) + getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.IRON_BOOTS)); + + for (int i=0 ; i 16) + return; + + + double power = 0.8 + (1.2 * ((dist-3)/13d)); + + //Leap + UtilAction.velocity(zombie, UtilAlg.getTrajectory(zombie, zombie.getTarget()), + power, false, 0, 0.2, 1, true); + + //Effect + zombie.getWorld().playSound(zombie.getLocation(), Sound.ZOMBIE_HURT, 1f, 2f); + } + + @EventHandler + public void onTarget(EntityTargetLivingEntityEvent event) + { + if (getEntity().equals(event.getEntity())) + { + if (!(event.getTarget() instanceof Player)) + { + event.setCancelled(true); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/ClansCurrency.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/ClansCurrency.java new file mode 100644 index 00000000..ba1b7504 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/ClansCurrency.java @@ -0,0 +1,10 @@ +package mineplex.game.clans.economy; + +import mineplex.core.common.currency.Currency; +import mineplex.core.common.util.C; +import org.bukkit.Material; + +public class ClansCurrency +{ + public static final Currency GOLD = new Currency("Gold", "Gold", C.cGold, Material.GOLD_NUGGET); +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GemTransfer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GemTransfer.java new file mode 100644 index 00000000..983ff6ec --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GemTransfer.java @@ -0,0 +1,49 @@ +package mineplex.game.clans.economy; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import mineplex.serverdata.data.Data; + +public class GemTransfer implements Data +{ + private static DateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy"); + + private String _playerName; + private Date _date; + + public GemTransfer(String playerName) + { + _playerName = playerName; + _date = new Date(); + } + + public boolean transferWasToday() + { + return currentDate().before(_date); + } + + @Override + public String getDataId() + { + return _playerName; + } + + /** + * @return the current date, with hours/minutes/seconds defaulted to 00:00, 12:00am of the + * current day. + */ + public static Date currentDate() + { + Date current = new Date(); + + try + { + return dateFormatter.parse(dateFormatter.format(current)); + } + catch (Exception exception) { } + + return null; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldCommand.java new file mode 100644 index 00000000..dd8e46dc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldCommand.java @@ -0,0 +1,79 @@ +package mineplex.game.clans.economy; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; + +public class GoldCommand extends CommandBase +{ + public GoldCommand(GoldManager plugin) + { + super(plugin, GoldManager.Perm.GIVE_GOLD_COMMAND, "givegold"); + } + + @Override + public void Execute(final Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Gold", "Missing Args: " + F.elem("/givegold "))); + return; + } + + final String targetName = args[0]; + final String goldString = args[1]; + Player target = UtilPlayer.searchExact(targetName); + + if (target == null) + { + Plugin.getClientManager().loadClientByName(targetName, client -> + { + if (client != null) + { + rewardGold(caller, null, targetName, client.getAccountId(), goldString); + } + else + { + UtilPlayer.message(caller, F.main("Gold", "Could not find player " + F.name(targetName))); + } + }); + } + else + { + rewardGold(caller, target, target.getName(), Plugin.getClientManager().Get(target).getAccountId(), goldString); + } + } + + private void rewardGold(final Player caller, final Player target, final String targetName, final int accountId, String goldString) + { + try + { + int gold = Integer.parseInt(goldString); + rewardGold(caller, target, targetName, accountId, gold); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main("Gold", "Invalid Gold Amount")); + } + } + + private void rewardGold(final Player caller, final Player target, final String targetName, final int accountId, final int gold) + { + Plugin.rewardGold(success -> + { + if (!success) + { + UtilPlayer.message(caller, F.main("Gold", "You cannot deduct that much " + F.elem("Gold") + " from " + F.name(targetName) + ".")); + return; + } + UtilPlayer.message(caller, F.main("Gold", "You gave " + F.elem(gold + " Gold") + " to " + F.name(targetName) + ".")); + + if (target != null) + { + UtilPlayer.message(target, F.main("Gold", F.name(caller.getName()) + " gave you " + F.elem(gold + " Gold") + ".")); + } + }, accountId, targetName, gold, true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldData.java new file mode 100644 index 00000000..e245169e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldData.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.economy; + +public class GoldData +{ + private int balance; + + public void addBalance(int amount) + { + balance += amount; + } + + public void setBalance(int amount) + { + balance = amount; + } + + public int getBalance() + { + return balance; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldManager.java new file mode 100644 index 00000000..c01515c3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldManager.java @@ -0,0 +1,452 @@ +package mineplex.game.clans.economy; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +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 org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.util.Vector; + +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.donation.DonationManager; +import mineplex.core.donation.Donor; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansDataAccessLayer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.items.economy.GoldToken; +import mineplex.game.clans.shop.bank.BankShop; + +public class GoldManager extends MiniDbClientPlugin +{ + public enum Perm implements Permission + { + GIVE_GOLD_COMMAND, + SET_GOLD_COMMAND, + } + public static final double GEM_CONVERSION_RATE = 16; // The number of gold coins when converted from a single gem + + public static final double DEATH_TAX = 0.04d; // Percentage of gold lost on death + public static final String META_STRING = "clans.goldAmount"; + + private static GoldManager _instance; + + public static GoldManager getInstance() + { + return _instance; + } + + private DonationManager _donationManager; + private final int _serverId; + private TransferTracker _transferTracker; + private Set _itemSet; + private Map _playerPickupMap; + + public GoldManager(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager, ClansDataAccessLayer dataAccessLayer) + { + super("Clans Gold", plugin.getPlugin(), clientManager); + + _instance = this; + _donationManager = donationManager; + _serverId = dataAccessLayer.getRepository().getServerId(); + _transferTracker = new TransferTracker(); + _itemSet = new HashSet<>(); + _playerPickupMap = new HashMap<>(); + new BankShop(plugin, clientManager, donationManager); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.GIVE_GOLD_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.SET_GOLD_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new GoldCommand(this)); + addCommand(new SetGoldCommand(this)); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) + { + final Player player = event.getEntity(); + + int gold = getGold(player); + final int droppedGold = (int) (gold * DEATH_TAX); + final Location deathLocation = player.getLocation(); + + if (droppedGold > 0) + { + deductGold(success -> + { + if (!success) + { + return; + } + runSync(() -> + { + GoldManager.notify(player, "You dropped " + F.elem(droppedGold + "") + " gold on your death!"); + + dropGold(deathLocation, droppedGold); + }); + }, player, droppedGold); + } + } + + @EventHandler + public void playerCmd(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().startsWith("/gold")) + { + notify(event.getPlayer(), "Your Balance is " + C.cYellow + getGold(event.getPlayer()) + "g"); + event.setCancelled(true); + } + } + + @EventHandler(ignoreCancelled = true) + public void onPickup(PlayerPickupItemEvent event) + { + if (_itemSet.contains(event.getItem())) + { + event.setCancelled(true); + + int goldAmount = 1; + List meta = event.getItem().getMetadata(META_STRING); + if (meta != null && meta.size() == 1) + { + goldAmount = meta.get(0).asInt(); + } + + event.getItem().remove(); + event.getPlayer().playSound(event.getPlayer().getEyeLocation(), Sound.ORB_PICKUP, 1F, 2F); + addGold(event.getPlayer(), goldAmount); + + int pickupMapGold = goldAmount; + if (_playerPickupMap.containsKey(event.getPlayer())) + { + pickupMapGold += _playerPickupMap.get(event.getPlayer()); + } + + _playerPickupMap.put(event.getPlayer(), pickupMapGold); + } + } + + @EventHandler + public void notifyPickup(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Map.Entry entry : _playerPickupMap.entrySet()) + { + if (entry.getKey().isOnline()) + { + notify(entry.getKey(), "You picked up " + F.elem(entry.getValue() + " gold")); + } + } + + _playerPickupMap.clear(); + } + + @EventHandler + public void cleanItems(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) return; + + Iterator itemIterator = _itemSet.iterator(); + + while (itemIterator.hasNext()) + { + Item item = itemIterator.next(); + + if (!item.isValid() || item.getTicksLived() >= 12000) // 10 minutes + { + item.remove(); + itemIterator.remove(); + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onChunkUnload(ChunkUnloadEvent event) + { + List entities = Arrays.asList(event.getChunk().getEntities()); + _itemSet.stream().filter(entities::contains).forEach(Item::remove); + } + + public int getGold(Player player) + { + return Get(player).getBalance(); + } + + public int getGems(Player player) + { + return getDonor(player).getBalance(GlobalCurrency.GEM); + } + + public void transferGemsToCoins(Player player, int gemAmount) + { + int gemCount = getGems(player); + int goldCount = (int) (((double) gemAmount) * GEM_CONVERSION_RATE); + + if (gemCount >= gemAmount) + { + _donationManager.rewardCurrency(GlobalCurrency.GEM, player, "GoldManager", -gemAmount); + addGold(player, goldCount); + notify(player, String.format("You have transferred %d gems into %d gold coins!", gemAmount, goldCount)); + _transferTracker.insertTransfer(player); + } + } + + /** + * @param player - the player to be checked for whether they can transfer gems into coins + * @return true, if the player has not converted gems into coins within the + * last day, false otherwise. + */ + public boolean canTransferGems(Player player) + { + return !_transferTracker.hasTransferredToday(player); + } + + public void cashIn(Player player, GoldToken token) + { + int value = token.getGoldValue(); + addGold(player, value); + notify(player, String.format("You have cashed in a gold token worth %dg!", value)); + } + + public void dropGold(Location location, int amount) + { + dropGold(location, amount, 0.15); + } + + public void dropGold(Location location, int amount, double velMult) + { + int count = amount / 1000; + + if (count > 75) + { + double x = Math.random() * 2 * Math.PI; + Vector velocity = new Vector(Math.sin(x), 0, Math.cos(x)); + dropGold(location, amount, velocity, velMult, "Gold " + 0); + return; + } + + int extraGold = amount % 1000; + + for (int i = 0; i < count; i++) + { + double x = Math.random() * 2 * Math.PI; + Vector velocity = new Vector(Math.sin(x), 0, Math.cos(x)); + dropGold(location, 1000, velocity, velMult, "Gold " + i); + } + + // Drop Extra + if (extraGold > 0) + { + double x = Math.random() * 2 * Math.PI; + Vector velocity = new Vector(Math.sin(x), 0, Math.cos(x)); + dropGold(location, extraGold, velocity, velMult, "extra gold"); + } + } + + private void dropGold(Location location, int amount, Vector velocity, double velMult, String name) + { + ItemStack stack = new ItemStack(Material.GOLD_NUGGET); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(name); + stack.setItemMeta(meta); + + Item item = location.getWorld().dropItem(location, stack); + item.setPickupDelay(40); + item.setMetadata(META_STRING, new FixedMetadataValue(getPlugin(), amount)); + + _itemSet.add(item); + + // Velocity + UtilAction.velocity(item, velocity, velMult, false, 0, 0.2, 0.2, false); + } + + public void purchaseToken(final Player player, final int tokenValue) + { + final GoldToken token = new GoldToken(tokenValue); + deductGold(success -> + { + if (success) + { + player.getInventory().addItem(token.toItemStack()); + GoldManager.notify(player, String.format("You have purchased a gold token worth %dg!", tokenValue)); + } + else + { + GoldManager.notify(player, String.format("You have purchased a gold token worth %dg!", tokenValue)); + } + }, player, tokenValue); + } + + + private Donor getDonor(Player player) + { + return _donationManager.Get(player); + } + + public static void notify(Player player, String message) + { + UtilPlayer.message(player, F.main("Gold", message)); + } + + @Override + public void disable() + { + for (Item item : _itemSet) + { + item.remove(); + } + } + + public void setGold(final Callback callback, final String caller, final String name, final int accountId, final int amount, final boolean updateTotal) + { + _donationManager.getGoldRepository().setGold(success -> + { + if (success.booleanValue()) + { + if (updateTotal) + { + GoldData data = Get(name); + + if (data != null) + { + data.setBalance(amount); + } + } + } + else + { + System.out.println("SET GOLD FAILED..."); + } + + if (callback != null) + { + callback.run(success); + } + }, _serverId, accountId, amount); + } + + public void addGold(Player player, int amount) + { + if (amount >= 0) + { + rewardGold(null, player, amount, true); + } + } + + public void deductGold(Callback resultCallback, Player player, int amount) + { + if (amount > 0) + { + rewardGold(resultCallback, player, -amount, true); + } + if (amount == 0 && resultCallback != null) + { + resultCallback.run(true); + } + } + + public void rewardGold(final Callback callback, final Player player, final int amount, final boolean updateTotal) + { + rewardGold(callback, getClientManager().Get(player).getAccountId(), player.getName(), amount, updateTotal); + } + + public void rewardGold(final Callback callback, int accountId, String name, final int amount, final boolean updateTotal) + { + if (amount == 0) + { + if (callback != null) + { + callback.run(true); + } + return; + } + + _donationManager.getGoldRepository().rewardGold(success -> + { + if (success.booleanValue()) + { + if (updateTotal) + { + GoldData data = Get(name); + + if (data != null) + { + data.addBalance(amount); + } + } + } + else + { + System.out.println("REWARD GOLD FAILED..."); + } + + if (callback != null) + { + callback.run(success); + } + }, _serverId, accountId, amount); + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT gold FROM clansGold WHERE accountId = '" + accountId + "' AND serverId=" + _serverId + ";"; + } + + @Override + public void processLoginResultSet(String playerName, UUID playerUUID, int accountId, ResultSet resultSet) throws SQLException + { + if (resultSet.next()) + { + Get(playerUUID).setBalance(resultSet.getInt(1)); + } + } + + @Override + protected GoldData addPlayer(UUID uuid) + { + return new GoldData(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldPurchaseProcessor.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldPurchaseProcessor.java new file mode 100644 index 00000000..9f1c71a7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldPurchaseProcessor.java @@ -0,0 +1,78 @@ +package mineplex.game.clans.economy; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.server.util.TransactionResponse; +import mineplex.core.shop.confirmation.ConfirmationCallback; +import mineplex.core.shop.confirmation.ConfirmationProcessor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +public class GoldPurchaseProcessor implements ConfirmationProcessor +{ + private final Player _player; + private final int _price; + private final GoldManager _goldManager; + private final Runnable _runAfterPurchase; + + public GoldPurchaseProcessor(Player player, int price, GoldManager goldManager, Runnable runAfterPurchase) + { + _player = player; + _price = price; + _goldManager = goldManager; + _runAfterPurchase = runAfterPurchase; + } + + @Override + public void init(Inventory inventory) + { + inventory.setItem(4, new ItemBuilder(ClansCurrency.GOLD.getDisplayMaterial()).setTitle(ClansCurrency.GOLD.getPrefix()).addLore(C.cGray + _price + " " + ClansCurrency.GOLD.getPrefix() + " will be", C.cGray + "deducted from your account balance").build()); + } + + @Override + public void process(ConfirmationCallback callback) { + int goldCount = _goldManager.Get(_player).getBalance(); + + if (_price > goldCount) + { + showResults(callback, TransactionResponse.InsufficientFunds); + } + else + { + _goldManager.rewardGold(data -> + { + if (data) + { + showResults(callback, TransactionResponse.Success); + _player.playSound(_player.getLocation(), Sound.LEVEL_UP, 2f, 1.5f); + } + else + { + showResults(callback, TransactionResponse.Failed); + } + }, _player, -_price, true); + + } + } + + private void showResults(ConfirmationCallback callback, TransactionResponse response) + { + switch (response) + { + case Failed: + callback.reject("There was an error processing your request."); + break; + case AlreadyOwns: + callback.reject("You already own this package."); + break; + case InsufficientFunds: + callback.reject("Your account has insufficient funds."); + break; + case Success: + callback.resolve("Your purchase was successful."); + _runAfterPurchase.run(); + break; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/SetGoldCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/SetGoldCommand.java new file mode 100644 index 00000000..1dce0b57 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/SetGoldCommand.java @@ -0,0 +1,67 @@ +package mineplex.game.clans.economy; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; + +public class SetGoldCommand extends CommandBase +{ + public SetGoldCommand(GoldManager plugin) + { + super(plugin, GoldManager.Perm.SET_GOLD_COMMAND, "setgold"); + } + + @Override + public void Execute(final Player caller, String[] args) + { + if (args == null || args.length < 2) + { + UtilPlayer.message(caller, F.main("Clans", "Error! Usage: " + F.elem("/setgold "))); + return; + } + + final String targetName = args[0]; + final String goldString = args[1]; + Player target = UtilPlayer.searchExact(targetName); + + try + { + if (target == null) + { + Plugin.getClientManager().loadClientByName(targetName, client -> + { + if (client != null) + { + setGold(caller, null, targetName, client.getAccountId(), Integer.parseInt(goldString)); + } + else + { + UtilPlayer.message(caller, F.main("Gold", "Could not find player " + F.name(targetName))); + } + }); + } + else + { + setGold(caller, target, target.getName(), Plugin.getClientManager().Get(target).getAccountId(), Integer.parseInt(goldString)); + } + } + catch (Exception e) + { + UtilPlayer.message(target, F.main("Clans", "You must provide a valid number in the gold parameter.")); + } + } + + private void setGold(final Player caller, final Player target, final String targetName, final int accountId, final int gold) + { + Plugin.setGold(new Callback() + { + public void run(Boolean completed) + { + UtilPlayer.message(caller, F.main("Gold", "You set " + F.name(targetName) + "'s Gold to " + F.elem(gold) + ".")); + } + }, caller.getName(), targetName, accountId, gold, true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/TransferTracker.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/TransferTracker.java new file mode 100644 index 00000000..b68aea0b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/economy/TransferTracker.java @@ -0,0 +1,37 @@ +package mineplex.game.clans.economy; + +import org.bukkit.entity.Player; + +import mineplex.serverdata.Region; +import mineplex.serverdata.data.DataRepository; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; + +/** + * Tracks when a player last converted gems into coins. + * @author MrTwiggy + * + */ +public class TransferTracker +{ + public static final int TRANSFER_TIMEOUT = 24 * 60 * 60; // Time before transfer entry expires from DB (in seconds) + private DataRepository _repository; + + public TransferTracker() + { + _repository = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), + Region.currentRegion(), GemTransfer.class, "GemTransfers"); + } + + public void insertTransfer(Player player) + { + GemTransfer transfer = new GemTransfer(player.getName()); + _repository.addElement(transfer, TRANSFER_TIMEOUT); + } + + public boolean hasTransferredToday(Player player) + { + GemTransfer transfer = _repository.getElement(player.getName()); + return transfer != null && transfer.transferWasToday(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/Field.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/Field.java new file mode 100644 index 00000000..66d68f97 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/Field.java @@ -0,0 +1,43 @@ +package mineplex.game.clans.fields; + +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.creature.Creature; +import mineplex.core.energy.Energy; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.fields.repository.FieldRepository; +import mineplex.minecraft.game.core.condition.ConditionManager; + +public class Field extends MiniPlugin +{ + private FieldBlock _block; + private FieldOre _ore; + private FieldMonster _mob; + + public Field(JavaPlugin plugin, Creature creature, ConditionManager condition, + ClansManager clansManager, Energy energy, String serverName) + { + super("Field Factory", plugin); + + FieldRepository repository = new FieldRepository(plugin); + _block = new FieldBlock(plugin, condition, clansManager, energy, repository, serverName); + _ore = new FieldOre(plugin, repository, serverName); + _mob = new FieldMonster(plugin, repository, creature, serverName); + } + + public FieldBlock GetBlock() + { + return _block; + } + + public FieldOre GetOre() + { + return _ore; + } + + public FieldMonster GetMonster() + { + return _mob; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlock.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlock.java new file mode 100644 index 00000000..b7b82b87 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlock.java @@ -0,0 +1,330 @@ +package mineplex.game.clans.fields; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; + +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.energy.Energy; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.fields.commands.FieldBlockCommand; +import mineplex.game.clans.fields.repository.FieldBlockToken; +import mineplex.game.clans.fields.repository.FieldRepository; +import mineplex.minecraft.game.core.condition.ConditionFactory; +import mineplex.minecraft.game.core.condition.ConditionManager; + +public class FieldBlock extends MiniPlugin +{ + public enum Perm implements Permission + { + FIELD_BLOCK_COMMAND, + } + + private ConditionFactory _conditionFactory; + private Energy _energy; + private FieldRepository _repository; + private Map _blocks; + private ClansManager _clansManager; + + private Set _active = new HashSet<>(); + + //Player Info + private Map _title = new WeakHashMap<>(); + private Map _stock = new WeakHashMap<>(); + private Map _regen = new WeakHashMap<>(); + private Map _emptyId = new WeakHashMap<>(); + private Map _emptyData = new WeakHashMap<>(); + private Map _lootString = new WeakHashMap<>(); + + private String _serverName; + + public FieldBlock(JavaPlugin plugin, ConditionManager condition, ClansManager clansManager, + Energy energy, FieldRepository repository, String serverName) + { + super("Field Block", plugin); + + _conditionFactory = condition.Factory(); + _energy = energy; + _repository = repository; + _clansManager = clansManager; + _blocks = new HashMap<>(); + + _serverName = serverName; + + load(); + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.FIELD_BLOCK_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new FieldBlockCommand(this)); + } + + public void showSettings(Player caller) + { + populateSettings(caller); + + UtilPlayer.message(caller, F.main(getName(), "Field Addition Settings;")); + UtilPlayer.message(caller, F.desc("Title", _title.get(caller))); + UtilPlayer.message(caller, F.desc("Stock", _stock.get(caller)+"")); + UtilPlayer.message(caller, F.desc("Regen", _regen.get(caller)+"")); + UtilPlayer.message(caller, F.desc("Empty", _emptyId.get(caller) + ":" + _emptyData.get(caller))); + UtilPlayer.message(caller, F.desc("Loot", _lootString.get(caller))); + } + + private void populateSettings(Player caller) + { + if (!_title.containsKey(caller)) _title.put(caller, "Default"); + if (!_stock.containsKey(caller)) _stock.put(caller, 1); + if (!_regen.containsKey(caller)) _regen.put(caller, 3d); + if (!_emptyId.containsKey(caller)) _emptyId.put(caller, 1); + if (!_emptyData.containsKey(caller)) _emptyData.put(caller, (byte)0); + if (!_lootString.containsKey(caller)) _lootString.put(caller, "263:0:2:1:50"); + } + + public void help(Player caller) + { + UtilPlayer.message(caller, F.main(_moduleName, "Commands List;")); + UtilPlayer.message(caller, F.help("/fo toggle", "Toggle Tools", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fb loot ", "Set Loot", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fb empty ", "Set Empty Block", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fb stock <#>", "Set Stock Max", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fb regen ", "Set Stock Regen", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fb wipe", "Delete All Block Fields (Database)", ChatColor.DARK_RED)); + } + + @EventHandler + public void handleInteract(PlayerInteractEvent event) + { + if (!_active.contains(event.getPlayer().getName())) + return; + + if (event.getPlayer().getItemInHand() != null && event.getPlayer().getItemInHand().getType().toString().contains("PICKAXE")) + { + if (UtilEvent.isAction(event, ActionType.R_BLOCK)) + showBlock(event.getPlayer(), event); + } + + else if (UtilGear.isMat(event.getPlayer().getItemInHand(), Material.GLOWSTONE_DUST)) + { + if (UtilEvent.isAction(event, ActionType.L_BLOCK)) + addBlock(event.getPlayer(), event); + + else if (UtilEvent.isAction(event, ActionType.R)) + glowBlocks(event.getPlayer(), event); + } + + else if (UtilGear.isMat(event.getPlayer().getItemInHand(), Material.REDSTONE)) + { + if (UtilEvent.isAction(event, ActionType.L_BLOCK)) + delBlock(event.getPlayer(), event); + + else if (UtilEvent.isAction(event, ActionType.R)) + glowBlocks(event.getPlayer(), event); + } + } + + private void glowBlocks(Player player, PlayerInteractEvent event) + { + load(); + + for (FieldBlockData cur : _blocks.values()) + cur.getBlock().setTypeId(89); + + event.setCancelled(true); + } + + public void wipe(Player player) + { + for (FieldBlockData cur : _blocks.values()) + { + cur.setEmpty(); + _repository.deleteFieldBlock(cur.getServer(), UtilWorld.locToStr(cur.getLocation())); + } + + _blocks.clear(); + + UtilPlayer.message(player, F.main(_moduleName, "Full Field Wipe Completed.")); + } + + private void delBlock(Player player, PlayerInteractEvent event) + { + String locString = UtilWorld.locToStr(event.getClickedBlock().getLocation()); + FieldBlockData block = _blocks.get(locString); + if (block != null) + { + _repository.deleteFieldBlock(block.getServer(), locString); + + //Inform + event.getClickedBlock().getWorld().playEffect(event.getClickedBlock().getLocation(), Effect.STEP_SOUND, 42); + UtilPlayer.message(player, F.main(_moduleName, "Field Block removed.")); + + event.setCancelled(true); + } + } + + private void addBlock(Player player, PlayerInteractEvent event) + { + populateSettings(player); + showSettings(player); + + FieldBlockToken token = new FieldBlockToken(); + + token.Server = "ALL"; + token.Location = UtilWorld.locToStr(event.getClickedBlock().getLocation()); + token.BlockId = event.getClickedBlock().getTypeId(); + token.BlockData = event.getClickedBlock().getData(); + token.EmptyId = _emptyId.get(player); + token.EmptyData = _emptyData.get(player); + token.StockMax = _stock.get(player); + token.StockRegenTime = _regen.get(player); + token.Loot = _lootString.get(player); + + _repository.addFieldBlock(token); + + //Inform + event.getClickedBlock().getWorld().playEffect(event.getClickedBlock().getLocation(), Effect.STEP_SOUND, 41); + UtilPlayer.message(player, F.main(_moduleName, "Field Block added.")); + + event.setCancelled(true); + } + + private void showBlock(Player player, PlayerInteractEvent event) + { + FieldBlockData fieldBlock = getFieldBlock(event.getClickedBlock()); + if (fieldBlock == null) return; + + fieldBlock.showInfo(player); + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void BlockBreak(BlockBreakEvent event) + { + if (_clansManager.isFields(event.getBlock().getLocation())) + { + event.setCancelled(true); // Cancel all block breaks in fields. Handle custom breaking for FieldBlocks and Ores. + + FieldBlockData fieldBlock = getFieldBlock(event.getBlock()); + if (fieldBlock != null) + { + fieldBlock.handleMined(event.getPlayer()); + } + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + for (FieldBlockData cur : _blocks.values()) + cur.regen(); + + if (event.getType() == UpdateType.FAST) + for (FieldBlockData cur : _blocks.values()) + cur.check(); + } + + public void load() + { + clean(); + + for (FieldBlockToken token : _repository.getFieldBlocks(_serverName)) + { + Location loc = UtilWorld.strToLoc(token.Location); + _blocks.put(token.Location, new FieldBlockData(this, token.Server, loc, token.BlockId, token.BlockData, token.EmptyId, token.EmptyData, token.StockMax, token.StockRegenTime, token.Loot)); + } + } + + public void clean() + { + for (FieldBlockData cur : _blocks.values()) + cur.clean(); + + _blocks.clear(); + } + + public FieldBlockData getFieldBlock(Block block) + { + if (_blocks.containsKey(UtilWorld.locToStr(block.getLocation()))) + return _blocks.get(UtilWorld.locToStr(block.getLocation())); + + return null; + } + + public Energy getEnergy() + { + return _energy; + } + + public Set getActive() + { + return _active; + } + + public Map getLootString() + { + return _lootString; + } + + public Map getEmptyId() + { + return _emptyId; + } + + public Map getEmptyData() + { + return _emptyData; + } + + public Map getRegen() + { + return _regen; + } + + public Map getStock() + { + return _stock; + } + + public Map getTitle() + { + return _title; + } + + public ConditionFactory getCondition() + { + return _conditionFactory; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlockData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlockData.java new file mode 100644 index 00000000..997f8b3d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlockData.java @@ -0,0 +1,227 @@ +package mineplex.game.clans.fields; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.itemstack.ItemStackFactory; + +public class FieldBlockData +{ + //Block + private String _server; + private Location _loc; + + private List _loot; + + private int _stockCur; + private int _stockMax; + + private int _blockId; + private byte _blockData; + + private int _emptyId; + private byte _emptyData; + + private long _regenTime; + private long _breakTime; + + private FieldBlock Field; + + //Constructor + public FieldBlockData(FieldBlock field, String server, Location loc, + int blockId, byte blockData, int emptyId, byte emptyData, + int stockMax, double regenTime, String lootString) + { + Field = field; + + //Block + _server = server; + _loc = loc; + + //Loot + _loot = new ArrayList(); + for (String cur : lootString.split(",")) + { + String[] loot = cur.split(":"); + + if (loot.length != 5) + { + System.out.println("Loot Failure: " + cur); + continue; + } + + //Parse and Add + try + { + _loot.add(new FieldBlockLootData(Integer.parseInt(loot[0]), + Byte.parseByte(loot[1]), + Integer.parseInt(loot[2]), + Integer.parseInt(loot[3]), + Integer.parseInt(loot[4]))); + } + catch (Exception e) + { + System.out.println("Loot Failure: " + cur); + } + } + + _stockCur = 0; + _stockMax = stockMax; + + _blockId = blockId; + _blockData = blockData; + + _emptyId = emptyId; + _emptyData = emptyData; + + _regenTime = (long)(regenTime * 60000); + _breakTime = 0; + + //Start Ore + regen(); + } + + public void check() + { + //Correct Block + if (_stockCur >= 1) + if (_loc.getBlock().getTypeId() != _blockId) + { + //89 is used to display Field Blocks + if (_loc.getBlock().getTypeId() != 89) + _stockCur--; + + _loc.getBlock().setTypeIdAndData(_blockId, _blockData, false); + } + + if (_stockCur == 0) + if (_loc.getBlock().getTypeId() != _emptyId) + _loc.getBlock().setTypeIdAndData(_emptyId, _emptyData, false); + } + + public void regen() + { + //Maxed + if (_stockCur >= _stockMax) + return; + + //Cooldown + if (!UtilTime.elapsed(_breakTime, UtilField.scale(_regenTime))) + return; + + //Increase Ore + if (_stockCur == 0) + _loc.getBlock().setTypeIdAndData(_blockId, _blockData, false); + + _stockCur++; + _breakTime = System.currentTimeMillis(); + + //Effect + _loc.getWorld().playEffect(_loc, Effect.STEP_SOUND, _blockId); + } + + public void handleMined(Player player) + { + if (!Field.getEnergy().Use(player, "Mine Field Block", 60, true, true)) + return; + + //Set Break Time - Avoid Instant Regen + if (_stockCur == _stockMax) + _breakTime = System.currentTimeMillis(); + + //Loot + Change Block + if (_stockCur <= 0) + return; + + if (tryMine()) + { + //Effect + _loc.getWorld().playEffect(_loc, Effect.STEP_SOUND, _loc.getBlock().getTypeId()); + + _stockCur--; + if (_stockCur == 0) + _loc.getBlock().setTypeIdAndData(_emptyId, _emptyData, false); + } + + //Slow + Field.getCondition().Slow("Field Slow", player, player, 6, 1, false, true, false, false); + } + + public boolean tryMine() + { + if (_loot.isEmpty()) + return true; + + boolean dropped = false; + + for (FieldBlockLootData cur : _loot) + { + if (cur.drop()) + { + int amount = cur.base + UtilMath.r(cur.bonus+1); + _loc.getWorld().dropItemNaturally(_loc, ItemStackFactory.Instance.CreateStack(cur.id, cur.data, amount)); + dropped = true; + } + } + + return dropped; + } + + public void showInfo(Player player) + { + UtilPlayer.message(player, F.main("Field", "Block Information;")); + UtilPlayer.message(player, F.desc("Block Capacity", _stockCur + "/" + _stockMax)); + + if (_stockCur >= _stockMax) + UtilPlayer.message(player, F.desc("Block Regeneration", "Full Capacity")); + else + { + long time = UtilField.scale(_regenTime) - (System.currentTimeMillis() - _breakTime); + UtilPlayer.message(player, F.desc("Block Regeneration", + UtilTime.convertString(time, 1, TimeUnit.FIT))); + } + + for (FieldBlockLootData cur : _loot) + cur.showInfo(player); + } + + public String getServer() + { + return _server; + } + + public void clean() + { + _loc.getBlock().setTypeIdAndData(_emptyId, _emptyData, false); + } + + public Block getBlock() + { + return _loc.getBlock(); + } + + public Location getLocation() + { + return _loc; + } + + public void setEmpty() + { + getBlock().setTypeIdAndData(_emptyId, _emptyData, true); + } + + public boolean isEmpty() + { + return _stockCur == 0; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlockLootData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlockLootData.java new file mode 100644 index 00000000..3c906cf9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldBlockLootData.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.fields; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemStackFactory; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +public class FieldBlockLootData +{ + protected int id; + protected byte data; + protected int base; + protected int bonus; + protected int chance; + + public FieldBlockLootData(int idIn, byte dataIn, int baseIn, int bonusIn, int chanceIn) + { + id = idIn; + data = dataIn; + base = baseIn; + bonus = bonusIn; + chance = chanceIn; + + if (chance <= 0) chance = 1; + if (chance > 100) chance = 100; + + if (base <= 0) base = 1; + if (bonus < 0) bonus = 0; + } + + public boolean drop() + { + return (UtilMath.r(100) <= chance); + } + + public void showInfo(Player player) + { + String name = Material.getMaterial(id).toString(); + String amount = base + ""; + if (bonus > 0) + amount = base + " to " + (base+bonus); + + name = ItemStackFactory.Instance.GetName(id, data, false); + + UtilPlayer.message(player, F.desc(name, amount + " at " + chance + "%")); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldMonster.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldMonster.java new file mode 100644 index 00000000..7415ec2e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldMonster.java @@ -0,0 +1,199 @@ +package mineplex.game.clans.fields; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +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.UtilWorld; +import mineplex.core.creature.Creature; +import mineplex.game.clans.fields.commands.FieldMonsterCommand; +import mineplex.game.clans.fields.monsters.FieldMonsterBase; +import mineplex.game.clans.fields.repository.FieldMonsterToken; +import mineplex.game.clans.fields.repository.FieldRepository; + +public class FieldMonster extends MiniPlugin +{ + public enum Perm implements Permission + { + FIELD_MONSTER_COMMAND, + } + + private Creature _creature; + private FieldRepository _repository; + private Set _pits; + private String _serverName; + + private Map _input = new WeakHashMap(); + + public FieldMonster(JavaPlugin plugin, FieldRepository repository, Creature creature, String serverName) + { + super("Field Monster", plugin); + + _repository = repository; + _creature = creature; + _pits = new HashSet(); + _serverName = serverName; + + Load(); + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.FIELD_MONSTER_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new FieldMonsterCommand(this)); + } + + public void Help(Player caller) + { + UtilPlayer.message(caller, F.main(getName(), "Commands List;")); + UtilPlayer.message(caller, F.help("/fm type ", "Set Monster Type", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm max <#>", "Set Monster Limit", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm rate ", "Set Monster Rate", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm radius <#>", "Set Area Radius", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm height <#>", "Set Area Height", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm create ", "Create at your Location", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm delete ", "Delete Field", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm list", "List Monster Fields", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm info ", "Display Monster Field", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm kill", "Kills all Field Monsters", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fm wipe", "Delete All Monster Field (Database)", ChatColor.DARK_RED)); + } + + public void Create(Player caller, String name) + { + FieldMonsterInput input = _input.get(caller); + + if (input.type == null) + { + UtilPlayer.message(caller, F.main(getName(), "You have not set Monster Type.")); + return; + } + + for (FieldMonsterBase pit : _pits) + { + if (name.equalsIgnoreCase(pit.GetName())) + { + UtilPlayer.message(caller, F.main(getName(), "Monster Field with this name already exists.")); + return; + } + } + + FieldMonsterBase pit = new FieldMonsterBase(this, name, "ALL", input.type, input.mobMax, input.mobRate, caller.getLocation(), input.radius, input.height); + Add(pit, true); + + UtilPlayer.message(caller, F.main(getName(), "You created Monster Field.")); + pit.Display(caller); + } + + private void Add(FieldMonsterBase pit, boolean repo) + { + UtilServer.getServer().getPluginManager().registerEvents(pit, getPlugin()); + _pits.add(pit); + + if (repo) + _repository.addFieldMonster(pit.GetToken()); + } + + public void Delete(Player caller, String name) + { + HashSet remove = new HashSet(); + + for (FieldMonsterBase pit : _pits) + if (pit.GetName().equalsIgnoreCase(name)) + remove.add(pit); + + int i = remove.size(); + + for (FieldMonsterBase pit : remove) + Delete(pit, true); + + UtilPlayer.message(caller, F.main(getName(), "Deleted " + i + " Monster Field(s).")); + } + + private void Delete(FieldMonsterBase pit, boolean repo) + { + _pits.remove(pit); + pit.RemoveMonsters(); + HandlerList.unregisterAll(pit); + + if (repo) + _repository.deleteFieldMonster(pit.GetToken()); + } + + public void Wipe(Player player, boolean repo) + { + HashSet remove = new HashSet(); + + for (FieldMonsterBase pit : _pits) + remove.add(pit); + + _pits.clear(); + + for (FieldMonsterBase pit : remove) + Delete(pit, repo); + + UtilPlayer.message(player, F.main(_moduleName, "Field Monsters Wiped.")); + } + + private void Load() + { + Wipe(null, false); + + for (FieldMonsterToken token : _repository.getFieldMonsters(_serverName)) + { + System.out.println("Found FM token : " + token.Type + " " + token.Centre); + EntityType type = UtilEnt.searchEntity(null, token.Type, false); + if (type == null) + continue; + + Location loc = UtilWorld.strToLoc(token.Centre); + if (loc == null) + continue; + + FieldMonsterBase pit = new FieldMonsterBase(this, token.Name, _serverName, type, token.MobMax, token.MobRate, loc, token.Radius, token.Height); + Add(pit, false); + } + } + + private void Clean() + { + for (FieldMonsterBase pit : _pits) + pit.RemoveMonsters(); + } + + public Map getInput() + { + return _input; + } + + public Set getPits() + { + return _pits; + } + + public Creature getCreature() + { + return _creature; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldMonsterInput.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldMonsterInput.java new file mode 100644 index 00000000..ac3d0a60 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldMonsterInput.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.fields; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; + +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +public class FieldMonsterInput +{ + public enum CustomType + { + + } + + public EntityType type = null; + public CustomType customType = null; + + public int mobMax = 12; + public double mobRate = 1; + + public int radius = 12; + public int height = 4; + + public void Display(Player caller) + { + UtilPlayer.message(caller, F.main("Field Monster", "Field Monster Settings;")); + UtilPlayer.message(caller, F.desc("Type", type + "")); + UtilPlayer.message(caller, F.desc("Max", mobMax + "")); + UtilPlayer.message(caller, F.desc("Rate", mobRate + "")); + UtilPlayer.message(caller, F.desc("Radius", radius + "")); + UtilPlayer.message(caller, F.desc("Height ", height + "")); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldOre.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldOre.java new file mode 100644 index 00000000..9e1659d9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldOre.java @@ -0,0 +1,291 @@ +package mineplex.game.clans.fields; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.fields.commands.FieldOreCommand; +import mineplex.game.clans.fields.repository.FieldOreToken; +import mineplex.game.clans.fields.repository.FieldRepository; + +public class FieldOre extends MiniPlugin +{ + public enum Perm implements Permission + { + FIELD_ORE_COMMAND, + } + + private FieldRepository _repository; + private Set _active = new HashSet(); + + private List _oreInactive = new ArrayList(); + private List _oreActive = new ArrayList(); + + private Map _oreLocations = new HashMap(); + + private long _oreRegen = 0; + private long _oreRegenTime = 20000; + + private String _serverName; + + public FieldOre(JavaPlugin plugin, FieldRepository repository, String serverName) + { + super("Field Ore", plugin); + + _repository = repository; + _serverName = serverName; + + load(); + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.FIELD_ORE_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new FieldOreCommand(this)); + } + + public void help(Player caller) + { + UtilPlayer.message(caller, F.main(_moduleName, "Commands List;")); + UtilPlayer.message(caller, F.help("/fo toggle", "Toggle Tools", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fo list", "List Ores", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fo fill", "Set Ores to Ore", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fo reset", "Reset Ores to Stone", ChatColor.DARK_RED)); + UtilPlayer.message(caller, F.help("/fo wipe", "Delete All Ore Fields (Database)", ChatColor.DARK_RED)); + } + + @EventHandler + public void handleInteract(PlayerInteractEvent event) + { + if (!_active.contains(event.getPlayer().getName())) + return; + + if (UtilGear.isMat(event.getPlayer().getItemInHand(), Material.DIAMOND)) + { + if (UtilEvent.isAction(event, ActionType.L)) + addBlock(event.getPlayer(), event); + + else if (UtilEvent.isAction(event, ActionType.R_BLOCK)) + delBlock(event.getPlayer(), event); + } + } + + public void reset(Player player) + { + for (FieldOreData ore : _oreActive) + { + ore.SetActive(false); + _oreInactive.add(ore); + } + + _oreActive.clear(); + + UtilPlayer.message(player, F.main(_moduleName, "Field Ore Reset.")); + } + + public void fill(Player player) + { + while (!_oreInactive.isEmpty()) + _oreInactive.get(UtilMath.r(_oreInactive.size())).StartVein(2 + UtilMath.r(5)); + + UtilPlayer.message(player, F.main(_moduleName, "Field Ore Generated.")); + } + + public void list(Player player) + { + UtilPlayer.message(player, F.main(_moduleName, F.value("Total", ""+_oreLocations.size()))); + UtilPlayer.message(player, F.main(_moduleName, F.value("Active", ""+_oreActive.size()))); + UtilPlayer.message(player, F.main(_moduleName, F.value("Inactive", ""+_oreInactive.size()))); + } + + public void wipe(Player player) + { + reset(player); + + for (Map.Entry entry : _oreLocations.entrySet()) + { + _repository.deleteFieldOre(entry.getValue(), UtilWorld.locToStr(entry.getKey())); + } + + _oreInactive.clear(); + _oreLocations.clear(); + + UtilPlayer.message(player, F.main(_moduleName, "Field Ore Wiped.")); + } + + private void addBlock(Player player, PlayerInteractEvent event) + { + Block block = player.getTargetBlock(((Set) null), 0); + + if (Get(block.getLocation()) != null) + { + UtilPlayer.message(player, F.main(_moduleName, "This is already Field Ore.")); + return; + } + + //Repo + FieldOreToken token = new FieldOreToken(); + token.Server = "ALL"; + token.Location = UtilWorld.locToStr(block.getLocation()); + _repository.addFieldOre(token); + + //Memory + _oreInactive.add(new FieldOreData(this, token.Server, block.getLocation())); + + //Inform + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 57); + UtilPlayer.message(player, F.main(_moduleName, "Field Ore Added.")); + + event.setCancelled(true); + } + + private void delBlock(Player player, PlayerInteractEvent event) + { + event.setCancelled(true); + + FieldOreData ore = Get(event.getPlayer().getTargetBlock(((Set) null), 0).getLocation()); + + if (ore == null) + { + UtilPlayer.message(player, F.main(_moduleName, "This is not Field Ore.")); + return; + } + + _repository.deleteFieldOre(ore._server, UtilWorld.locToStr(event.getClickedBlock().getLocation())); + + ore.GetLocation().getBlock().setType(Material.STONE); + + ore.Delete(); + + _oreActive.remove(ore); + _oreInactive.remove(ore); + _oreLocations.remove(ore._loc); + + //Inform + event.getClickedBlock().getWorld().playEffect(event.getClickedBlock().getLocation(), Effect.STEP_SOUND, 57); + UtilPlayer.message(player, F.main(_moduleName, "Field Ore Removed.")); + } + + public FieldOreData Get(Location loc) + { + for (FieldOreData ore : _oreInactive) + if (ore.GetLocation().equals(loc)) + return ore; + + for (FieldOreData ore : _oreActive) + if (ore.GetLocation().equals(loc)) + return ore; + + return null; + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void Break(BlockBreakEvent event) + { + if (!_oreLocations.containsKey(event.getBlock().getLocation())) + return; + + FieldOreData ore = Get(event.getBlock().getLocation()); + + if (ore == null) + return; + + event.setCancelled(true); + + ore.OreMined(event.getPlayer(), event.getPlayer().getEyeLocation()); + } + + @EventHandler + private void Regenerate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + if (_oreInactive.isEmpty()) + return; + + if (!UtilTime.elapsed(_oreRegen, UtilField.scale(_oreRegenTime))) + return; + + _oreRegen = System.currentTimeMillis(); + + //Start! + _oreInactive.get(UtilMath.r(_oreInactive.size())).StartVein(2 + UtilMath.r(5)); + } + + public List GetActive() + { + return _oreActive; + } + + public List GetInactive() + { + return _oreInactive; + } + + public Map getLocationMap() + { + return _oreLocations; + } + + public void load() + { + clean(); + + for (FieldOreToken token : _repository.getFieldOres(_serverName)) + { + Location loc = UtilWorld.strToLoc(token.Location); + + loc.getBlock().setType(Material.STONE); + _oreInactive.add(new FieldOreData(this, token.Server, loc)); + _oreLocations.put(loc, token.Server); + } + } + + public void clean() + { + reset(null); + _oreInactive.clear(); + _oreActive.clear(); + _oreLocations.clear(); + } + + public Set getActivePlayers() + { + return _active; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldOreData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldOreData.java new file mode 100644 index 00000000..ad84146f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/FieldOreData.java @@ -0,0 +1,220 @@ +package mineplex.game.clans.fields; + +import java.util.HashSet; + +import org.bukkit.Effect; +import org.bukkit.Location; +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.util.Vector; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.game.clans.clans.pvptimer.PvPTimerManager; + +public class FieldOreData +{ + protected boolean _active = false; + + protected Location _loc = null; + protected String _server; + protected HashSet _neighbours = new HashSet(); + protected double _neighbourDist = 4; + + protected FieldOre Field; + + public FieldOreData(FieldOre field, String server, Location loc) + { + Field = field; + _loc = loc; + _server = server; + + Field.getLocationMap().put(_loc, server); + + for (FieldOreData other : Field.GetInactive()) + { + if (other.equals(this)) + continue; + + if (UtilMath.offset(_loc, other.GetLocation()) > _neighbourDist) + continue; + + AddNeighbour(other); + other.AddNeighbour(this); + } + + for (FieldOreData other : Field.GetActive()) + { + if (other.equals(this)) + continue; + + if (UtilMath.offset(_loc, other.GetLocation()) > _neighbourDist) + continue; + + AddNeighbour(other); + other.AddNeighbour(this); + } + } + + public void AddNeighbour(FieldOreData other) + { + _neighbours.add(other); + } + + public void RemoveNeighbour(FieldOreData other) + { + _neighbours.remove(other); + } + + public Location GetLocation() + { + return _loc; + } + + public boolean IsActive() + { + return _active; + } + + public void OreMined(Player player, Location source) + { + //Persist + OreLoot(player, source); + + if (Math.random() > 0.9) + return; + + Field.GetInactive().add(this); + Field.GetActive().remove(this); + + _loc.getBlock().setType(Material.STONE); + + _active = false; + } + + @SuppressWarnings("deprecation") + public void OreLoot(Player player, Location source) + { + ItemStack stack = null; + + Block block = _loc.getBlock(); + + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId()); + + if (block.getType() == Material.IRON_ORE) stack = ItemStackFactory.Instance.CreateStack(Material.IRON_INGOT); + else if (block.getType() == Material.GOLD_ORE) stack = ItemStackFactory.Instance.CreateStack(Material.GOLD_INGOT); + else if (block.getType() == Material.DIAMOND_ORE) stack = ItemStackFactory.Instance.CreateStack(Material.DIAMOND); + else if (block.getType() == Material.LAPIS_ORE) stack = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, (byte)4); + else if (block.getType() == Material.COAL_ORE) stack = ItemStackFactory.Instance.CreateStack(Material.COAL, 2); + else if (block.getType() == Material.REDSTONE_ORE) stack = ItemStackFactory.Instance.CreateStack(Material.REDSTONE, 3); + + if (stack == null) + { + return; + } + + if (!Managers.get(PvPTimerManager.class).handleMining(player, block, false, stack, false)) + { + Vector vec = UtilAlg.getTrajectory(_loc.getBlock().getLocation().add(0.5, 0.5, 0.5), source).normalize(); + + Item item = _loc.getWorld().dropItem(_loc.getBlock().getLocation().add(0.5, 0.5, 0.5).add(vec), stack); + item.setPickupDelay(40); + } + } + + public void StartVein(int veinSize) + { + _loc.getBlock().setType(OreSelect()); + + Field.GetInactive().remove(this); + Field.GetActive().add(this); + + _active = true; + + //Spread + OreSpread(veinSize); + } + + public void OreSpread(int veinSize) + { + if (veinSize <= 0) + return; + + //Spread To... + FieldOreData closest = null; + double dist = 10; + + for (FieldOreData other : _neighbours) + { + if (other.IsActive()) + continue; + + if (UtilMath.offset(_loc, other.GetLocation()) > dist) + continue; + + closest = other; + } + + if (closest == null) + return; + + closest.StartVein(veinSize - 1); + } + + public Material OreSelect() + { + //Similar + FieldOreData closest = null; + double dist = 10; + + for (FieldOreData other : _neighbours) + { + if (!other.IsActive()) + continue; + + if (UtilMath.offset(_loc, other.GetLocation()) > dist) + continue; + + closest = other; + } + + if (closest != null) + return closest.GetLocation().getBlock().getType(); + + + //Spread + double rand = Math.random(); + + if (rand < 0.32) return Material.IRON_ORE; + if (rand < 0.64) return Material.GOLD_ORE; + if (rand < 0.96) return Material.DIAMOND_ORE; + if (rand < 0.98) return Material.COAL_ORE; + //if (rand < 0.97) return Material.REDSTONE_ORE; + return Material.LAPIS_ORE; + } + + public void Delete() + { + for (FieldOreData other : _neighbours) + other.RemoveNeighbour(this); + + Field.getLocationMap().remove(_loc); + + _neighbours.clear(); + _neighbours = null; + _loc = null; + + System.out.println("Deleted"); + } + + public void SetActive(boolean active) + { + _active = active; + _loc.getBlock().setType(Material.STONE); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/UtilField.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/UtilField.java new file mode 100644 index 00000000..e2758e35 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/UtilField.java @@ -0,0 +1,12 @@ +package mineplex.game.clans.fields; + +import mineplex.core.common.util.UtilServer; + +public class UtilField +{ + public static long scale(long regenTime) + { + int players = 80 - Math.min(80, UtilServer.getPlayers().length); + return (long)(regenTime * (-16 * Math.log(Math.pow(8.01,2) - Math.pow(0.1*players,2)) + 67.6)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldBlockCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldBlockCommand.java new file mode 100644 index 00000000..67cc167c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldBlockCommand.java @@ -0,0 +1,134 @@ +package mineplex.game.clans.fields.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.fields.FieldBlock; + +public class FieldBlockCommand extends CommandBase +{ + public FieldBlockCommand(FieldBlock plugin) + { + super(plugin, FieldBlock.Perm.FIELD_BLOCK_COMMAND, "fb"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0 || args[0].equalsIgnoreCase("help")) + { + Plugin.help(caller); + } + else if (args[0].equalsIgnoreCase("toggle")) + { + if (!Plugin.getActive().remove(caller.getName())) + Plugin.getActive().add(caller.getName()); + + UtilPlayer.message(caller, F.main(Plugin.getName(), "Interact Active: " + F.tf(Plugin.getActive().contains(caller.getName())))); + } + else if (args[0].equalsIgnoreCase("load")) + { + Plugin.load(); + UtilPlayer.message(caller, F.main(Plugin.getName(), "Reloaded Field Blocks from Database.")); + } + else if (args[0].equalsIgnoreCase("wipe")) + { + Plugin.wipe(caller); + } + else if (args.length <= 1) + { + Plugin.help(caller); + } + else if (args[0].equalsIgnoreCase("title")) + { + Plugin.getTitle().put(caller, args[1]); + Plugin.showSettings(caller); + } + else if (args[0].equalsIgnoreCase("stock")) + { + try + { + int count = Integer.parseInt(args[1]); + if (count < 1) count = 1; + Plugin.getStock().put(caller, count); + Plugin.showSettings(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Stock Max.")); + } + } + else if (args[0].equalsIgnoreCase("regen")) + { + try + { + double regen = Double.parseDouble(args[1]); + if (regen < 0) regen = 0; + Plugin.getRegen().put(caller, UtilMath.trim(1, regen)); + Plugin.showSettings(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Stock Regeneration Time.")); + } + } + else if (args[0].equalsIgnoreCase("empty")) + { + try + { + String[] toks = args[1].split(":"); + + int id = Integer.parseInt(toks[0]); + byte data = Byte.parseByte(toks[1]); + + Plugin.getEmptyId().put(caller, id); + Plugin.getEmptyData().put(caller, data); + Plugin.showSettings(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Empty Block.")); + } + } + else if (args[0].equalsIgnoreCase("loot")) + { + boolean error = false; + for (String cur : args[1].split(",")) + { + String[] loot = cur.split(":"); + + if (loot.length != 5) + { + error = true; + break; + } + + try + { + Integer.parseInt(loot[0]); + Byte.parseByte(loot[1]); + Integer.parseInt(loot[2]); + Integer.parseInt(loot[3]); + Integer.parseInt(loot[4]); + } + catch (Exception e) + { + error = true; + break; + } + } + + if (error) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Loot String.")); + return; + } + + Plugin.getLootString().put(caller, args[1]); + Plugin.showSettings(caller); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldMonsterCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldMonsterCommand.java new file mode 100644 index 00000000..ff8d6457 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldMonsterCommand.java @@ -0,0 +1,169 @@ +package mineplex.game.clans.fields.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.fields.FieldMonster; +import mineplex.game.clans.fields.FieldMonsterInput; +import mineplex.game.clans.fields.monsters.FieldMonsterBase; + +public class FieldMonsterCommand extends CommandBase +{ + public FieldMonsterCommand(FieldMonster plugin) + { + super(plugin, FieldMonster.Perm.FIELD_MONSTER_COMMAND, "fm"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (!Plugin.getInput().containsKey(caller)) + Plugin.getInput().put(caller, new FieldMonsterInput()); + + FieldMonsterInput input = Plugin.getInput().get(caller); + + if (args == null || args.length == 0) + { + Plugin.getInput().get(caller).Display(caller); + UtilPlayer.message(caller, F.main(Plugin.getName(), "Type " + F.elem("/fm help") + " for commands.")); + } + + else if (args[0].equalsIgnoreCase("help")) + { + Plugin.Help(caller); + } + + else if (args[0].equalsIgnoreCase("type")) + { + try + { + input.type = UtilEnt.searchEntity(caller, args[1], true); + if (input.type != null) + input.Display(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Monster Type.")); + } + } + + else if (args[0].equalsIgnoreCase("max")) + { + try + { + int value = Integer.parseInt(args[1]); + if (value < 1) value = 1; + input.mobMax = value; + input.Display(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Monster Max.")); + } + } + + else if (args[0].equalsIgnoreCase("rate")) + { + try + { + double value = Double.parseDouble(args[1]); + if (value < 0) value = 0; + input.mobRate = value; + input.Display(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Monster Rate.")); + } + } + + else if (args[0].equalsIgnoreCase("radius")) + { + try + { + int integer = Integer.parseInt(args[1]); + if (integer < 1) integer = 1; + input.radius = integer; + input.Display(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Area Radius.")); + } + } + + else if (args[0].equalsIgnoreCase("height")) + { + try + { + int integer = Integer.parseInt(args[1]); + if (integer < 1) integer = 1; + input.height = integer; + input.Display(caller); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Area Height.")); + } + } + + else if (args[0].equalsIgnoreCase("create")) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Missing Monster Field Name.")); + } + else + { + Plugin.Create(caller, args[1]); + } + } + + else if (args[0].equalsIgnoreCase("delete")) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Missing Monster Field Name.")); + } + else + { + Plugin.Delete(caller, args[1]); + } + } + + else if (args[0].equalsIgnoreCase("list")) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Listing Monster Fields;")); + + for (FieldMonsterBase pit : Plugin.getPits()) + pit.Display(caller); + } + + else if (args[0].equalsIgnoreCase("info")) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Listing Monster Fields;")); + + for (FieldMonsterBase pit : Plugin.getPits()) + pit.Display(caller); + } + + else if (args[0].equalsIgnoreCase("wipe")) + { + Plugin.Wipe(caller, true); + } + + else if (args[0].equalsIgnoreCase("kill")) + { + for (FieldMonsterBase pit : Plugin.getPits()) + pit.RemoveMonsters(); + } + + else + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid Command.")); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldOreCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldOreCommand.java new file mode 100644 index 00000000..5c78bd47 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/commands/FieldOreCommand.java @@ -0,0 +1,59 @@ +package mineplex.game.clans.fields.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.fields.FieldOre; + +public class FieldOreCommand extends CommandBase +{ + public FieldOreCommand(FieldOre plugin) + { + super(plugin, FieldOre.Perm.FIELD_ORE_COMMAND, "fo"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length == 0) + { + Plugin.help(caller); + return; + } + + if (args[0].equalsIgnoreCase("toggle")) + { + if (!Plugin.getActivePlayers().remove(caller.getName())) + Plugin.getActivePlayers().add(caller.getName()); + + UtilPlayer.message(caller, F.main(Plugin.getName(), "Interact Active: " + F.tf(Plugin.getActivePlayers().contains(caller.getName())))); + } + + else if (args[0].equalsIgnoreCase("help")) + { + Plugin.help(caller); + } + + else if (args[0].equalsIgnoreCase("reset")) + { + Plugin.reset(caller); + } + + else if (args[0].equalsIgnoreCase("fill")) + { + Plugin.fill(caller); + } + + else if (args[0].equalsIgnoreCase("list")) + { + Plugin.list(caller); + } + + else if (args[0].equalsIgnoreCase("wipe")) + { + Plugin.wipe(caller); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/monsters/FieldMonsterBase.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/monsters/FieldMonsterBase.java new file mode 100644 index 00000000..9fe52c94 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/monsters/FieldMonsterBase.java @@ -0,0 +1,223 @@ +package mineplex.game.clans.fields.monsters; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityCombustEvent; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.fields.FieldMonster; +import mineplex.game.clans.fields.UtilField; +import mineplex.game.clans.fields.repository.FieldMonsterToken; +import net.minecraft.server.v1_8_R3.EntityCreature; +import net.minecraft.server.v1_8_R3.NavigationAbstract; + +public class FieldMonsterBase implements Listener +{ + public FieldMonster Manager; + + private String _name; + private String _serverName; + private EntityType _type; + + private int _mobMax; + private Map _mobs = new HashMap(); + + private List _locs = new ArrayList(); + + private double _mobRate = 0.5; + private long _mobLast = 0; + + private Location _centre; + private int _radius; + private int _height; + + public FieldMonsterBase(FieldMonster manager, String name, String serverName, EntityType type, int mobMax, double mobRate, Location centre, int radius, int height) + { + Manager = manager; + + _name = name; + _serverName = serverName; + _type = type; + + _mobMax = mobMax; + _mobRate = mobRate; + + _centre = centre; + _radius = radius; + _height = height; + + + PopulateLocations(); + } + + @EventHandler + public void Spawn(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + if (_locs.isEmpty()) + return; + + if (_mobs.size() >= _mobMax) + return; + + if (!UtilTime.elapsed(_mobLast, UtilField.scale((long) (_mobRate * 60000)))) + return; + + _mobLast = System.currentTimeMillis(); + + Entity ent = Manager.getCreature().SpawnEntity(SelectLocation(), _type); + _mobs.put(ent, 0); + } + + @EventHandler + public void Despawn(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + HashSet remove = new HashSet(); + + for (Entity mob : _mobs.keySet()) + if (mob == null || mob.isDead() || !mob.isValid()) + remove.add(mob); + + for (Entity mob : remove) + _mobs.remove(mob); + } + + @EventHandler + public void Return(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Entity mob : _mobs.keySet()) + if (UtilMath.offset2d(mob.getLocation(), _centre) > 2*_radius) + { + int time = _mobs.get(mob) + 1; + _mobs.put(mob, time); + + Location loc = SelectLocation(); + if (loc == null) + continue; + + //Move + if (time < 10) + { + EntityCreature ec = ((CraftCreature)mob).getHandle(); + NavigationAbstract nav = ec.getNavigation(); + nav.a(loc.getX(), loc.getY(), loc.getZ(), 0.2f); + } + + //Extreme + else + { + mob.teleport(loc); + } + } + else + { + _mobs.put(mob, 0); + } + } + + @EventHandler + public void Combust(EntityCombustEvent event) + { + if (_mobs.containsKey(event.getEntity())) + event.setCancelled(true); + } + + public void PopulateLocations() + { + int attempts = 0; + while (_locs.size() < (_radius*_radius) && attempts < 2000) + { + attempts++; + + Block block = _centre.getBlock().getRelative(UtilMath.r(_radius * 2) - _radius, UtilMath.r(_height * 2) - _height, UtilMath.r(_radius * 2) - _radius); + + if (!UtilBlock.solid(block)) + continue; + + if (!UtilBlock.airFoliage(block.getRelative(0,1,0))) + continue; + + if (!UtilBlock.airFoliage(block.getRelative(0,2,0))) + continue; + + if (_locs.contains(block.getLocation())) + continue; + + _locs.add(block.getLocation().add(0.5, 1.5, 0.5)); + } + } + + public Location SelectLocation() + { + if (_locs.isEmpty()) + return null; + + return _locs.get(UtilMath.r(_locs.size())); + } + + public double GetRadius() + { + return _radius; + } + + public String GetName() + { + return _name; + } + + public void Display(Player caller) + { + UtilPlayer.message(caller, F.value(_name, _type.toString() + " " + UtilWorld.locToStrClean(_centre))); + } + + public void RemoveMonsters() + { + for (Entity ent : _mobs.keySet()) + ent.remove(); + + _mobs.clear(); + } + + public FieldMonsterToken GetToken() + { + FieldMonsterToken token = new FieldMonsterToken(); + + token.Name = _name; + token.Server = _serverName; + token.Type = _type.toString(); + token.MobMax = _mobMax; + token.MobRate = _mobRate; + token.Centre = UtilWorld.locToStr(_centre); + token.Radius = _radius; + token.Height = _height; + + return token; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldBlockToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldBlockToken.java new file mode 100644 index 00000000..4185a608 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldBlockToken.java @@ -0,0 +1,14 @@ +package mineplex.game.clans.fields.repository; + +public class FieldBlockToken +{ + public String Server; + public String Location; + public int BlockId; + public byte BlockData; + public int EmptyId; + public byte EmptyData; + public int StockMax; + public double StockRegenTime; + public String Loot; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldMonsterToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldMonsterToken.java new file mode 100644 index 00000000..e85ba1e1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldMonsterToken.java @@ -0,0 +1,13 @@ +package mineplex.game.clans.fields.repository; + +public class FieldMonsterToken +{ + public String Name; + public String Server; + public String Type; + public int MobMax; + public double MobRate; + public String Centre; + public int Radius; + public int Height; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldOreToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldOreToken.java new file mode 100644 index 00000000..9ad5dc8e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldOreToken.java @@ -0,0 +1,7 @@ +package mineplex.game.clans.fields.repository; + +public class FieldOreToken +{ + public String Server; + public String Location; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldRepository.java new file mode 100644 index 00000000..5b4de59b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/fields/repository/FieldRepository.java @@ -0,0 +1,182 @@ +package mineplex.game.clans.fields.repository; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import mineplex.core.database.MinecraftRepository; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.ResultSetCallable; +import mineplex.serverdata.database.column.ColumnByte; +import mineplex.serverdata.database.column.ColumnDouble; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class FieldRepository extends RepositoryBase +{ + private static String ALL_STRING = "ALL"; + + private static String CREATE_FIELD_BLOCK_TABLE = "CREATE TABLE IF NOT EXISTS fieldBlock (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), location VARCHAR(100), blockId INT, blockData TINYINT, emptyId INT, emptyData TINYINT, stockMax INT, stockRegenTime DOUBLE, loot VARCHAR(100), PRIMARY KEY (id), INDEX serverLocation (server, location));"; + private static String CREATE_FIELD_ORE_TABLE = "CREATE TABLE IF NOT EXISTS fieldOre (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), location VARCHAR(100), PRIMARY KEY (id), INDEX serverLocation (server, location));"; + private static String CREATE_FIELD_MONSTER_TABLE = "CREATE TABLE IF NOT EXISTS fieldMonster (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), name VARCHAR(100), type VARCHAR(100), mobMax INT, mobRate DOUBLE, center VARCHAR(100), radius INT, height INT, PRIMARY KEY (id), INDEX serverName (server, name));"; + private static String RETRIEVE_FIELD_BLOCKS = "SELECT server, location, blockId, blockData, emptyId, emptyData, stockMax, stockRegenTime, loot FROM fieldBlock WHERE server = ? OR server = \"" + ALL_STRING + "\";"; + private static String ADD_FIELD_BLOCK = "INSERT INTO fieldBlock (server, location, blockId, blockData, emptyId, emptyData, stockMax, stockRegenTime, loot) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"; + private static String DEL_FIELD_BLOCK = "DELETE FROM fieldBlock WHERE server = ? AND location = ?;"; + private static String RETRIEVE_FIELD_ORES = "SELECT server, location FROM fieldOre WHERE server = ? OR server = \"" + ALL_STRING + "\";"; + private static String ADD_FIELD_ORE = "INSERT INTO fieldOre (server, location) VALUES (?, ?);"; + private static String DEL_FIELD_ORE = "DELETE FROM fieldOre WHERE server = ? AND location = ?;"; + private static String RETRIEVE_FIELD_MONSTERS = "SELECT server, name, type, mobMax, mobRate, center, radius, height FROM fieldMonster WHERE server = ? OR server = \"" + ALL_STRING + "\";"; + private static String ADD_FIELD_MONSTER = "INSERT INTO fieldMonster (server, name, type, mobMax, mobRate, center, radius, height) VALUES (?, ?, ?, ?, ?, ?, ?, ?);"; + private static String DEL_FIELD_MONSTER = "DELETE FROM fieldMonster WHERE server = ? AND name = ?;"; + + public FieldRepository(JavaPlugin plugin) + { + super(DBPool.getAccount()); + } + + public List getFieldBlocks(String server) + { + final List fieldBlocks = new ArrayList(); + + executeQuery(RETRIEVE_FIELD_BLOCKS, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + FieldBlockToken token = new FieldBlockToken(); + token.Server = resultSet.getString(1); + token.Location = resultSet.getString(2); + token.BlockId = resultSet.getInt(3); + token.BlockData = resultSet.getByte(4); + token.EmptyId = resultSet.getInt(5); + token.EmptyData = resultSet.getByte(6); + token.StockMax = resultSet.getInt(7); + token.StockRegenTime = resultSet.getLong(8); + token.Loot = resultSet.getString(9); + + fieldBlocks.add(token); + } + } + }, new ColumnVarChar("server", 100, server)); + + return fieldBlocks; + } + + public void addFieldBlock(FieldBlockToken token) + { + executeUpdate(ADD_FIELD_BLOCK, + new ColumnVarChar("server", 100, token.Server), + new ColumnVarChar("location", 100, token.Location), + new ColumnInt("blockId", token.BlockId), + new ColumnByte("blockData", token.BlockData), + new ColumnInt("emptyId", token.EmptyId), + new ColumnByte("emptyData", token.EmptyData), + new ColumnInt("stockMax", token.StockMax), + new ColumnDouble("stockRegen", token.StockRegenTime), + new ColumnVarChar("loot", 100, token.Loot) + ); + } + + public void deleteFieldBlock(String server, String location) + { + executeUpdate(DEL_FIELD_BLOCK, new ColumnVarChar("server", 100, server), new ColumnVarChar("location", 100, location)); + } + + public List getFieldOres(String server) + { + final List fieldOres = new ArrayList(); + + this.executeQuery(RETRIEVE_FIELD_ORES, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + FieldOreToken token = new FieldOreToken(); + token.Server = resultSet.getString(1); + token.Location = resultSet.getString(2); + + fieldOres.add(token); + } + } + }, new ColumnVarChar("server", 100, server)); + + return fieldOres; + } + + public void addFieldOre(FieldOreToken token) + { + executeUpdate(ADD_FIELD_ORE, + new ColumnVarChar("server", 100, token.Server), + new ColumnVarChar("location", 100, token.Location) + ); + } + + public void deleteFieldOre(String server, String location) + { + executeUpdate(DEL_FIELD_ORE, new ColumnVarChar("server", 100, server), new ColumnVarChar("location", 100, location)); + } + + public List getFieldMonsters(String server) + { + final List fieldMonsters = new ArrayList(); + + executeQuery(RETRIEVE_FIELD_MONSTERS, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + while (resultSet.next()) + { + FieldMonsterToken token = new FieldMonsterToken(); + token.Server = resultSet.getString(1); + token.Name = resultSet.getString(2); + token.Type = resultSet.getString(3); + token.MobMax = resultSet.getInt(4); + token.MobRate = resultSet.getDouble(5); + token.Centre = resultSet.getString(6); + token.Radius = resultSet.getInt(7); + token.Height = resultSet.getInt(8); + + fieldMonsters.add(token); + } + } + }, new ColumnVarChar("server", 100, server)); + + return fieldMonsters; + } + + public void addFieldMonster(FieldMonsterToken token) + { + executeUpdate(ADD_FIELD_MONSTER, + new ColumnVarChar("server", 100, token.Server), + new ColumnVarChar("name", 100, token.Name), + new ColumnVarChar("blockId", 100, token.Type), + new ColumnInt("mobMax", token.MobMax), + new ColumnDouble("mobRate", token.MobRate), + new ColumnVarChar("center", 100, token.Centre), + new ColumnInt("radius", token.Radius), + new ColumnInt("height", token.Height) + ); + } + + public void deleteFieldMonster(FieldMonsterToken token) + { + executeUpdate(DEL_FIELD_MONSTER, new ColumnVarChar("server", 100, token.Server), new ColumnVarChar("name", 100, token.Name)); + } + + @Override + protected void initialize() + { + executeUpdate(CREATE_FIELD_BLOCK_TABLE); + executeUpdate(CREATE_FIELD_ORE_TABLE); + executeUpdate(CREATE_FIELD_MONSTER_TABLE); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/CustomCreatures.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/CustomCreatures.java new file mode 100644 index 00000000..8dfc6ee3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/CustomCreatures.java @@ -0,0 +1,55 @@ +package mineplex.game.clans.gameplay; + +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; + +public class CustomCreatures implements Listener +{ + + private static final EntityType[] DISABLED_CREATURES = { EntityType.WITCH, EntityType.PIG_ZOMBIE, + EntityType.ENDERMAN }; + + private static final EntityType[] DISABLED_NATURAL = { EntityType.HORSE }; + + @EventHandler + public void onCreatureSpawn(CreatureSpawnEvent event) + { + if (isDisabledCreature(event.getEntityType())) + { + event.setCancelled(true); + } + if (isDisabledNatural(event.getEntityType()) && event.getSpawnReason() != SpawnReason.CUSTOM) + { + event.setCancelled(true); + } + } + + private boolean isDisabledCreature(EntityType entityType) + { + for (EntityType disabledCreature : DISABLED_CREATURES) + { + if (disabledCreature == entityType) + { + return true; + } + } + + return false; + } + + private boolean isDisabledNatural(EntityType entityType) + { + for (EntityType disabledCreature : DISABLED_NATURAL) + { + if (disabledCreature == entityType) + { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/CustomRecipes.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/CustomRecipes.java new file mode 100644 index 00000000..43ed555d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/CustomRecipes.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.gameplay; + +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.inventory.Recipe; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; + +public class CustomRecipes implements Listener +{ + private static final Material[] DISABLED_RECIPES = { Material.EXPLOSIVE_MINECART, Material.MINECART, Material.JUKEBOX, Material.FISHING_ROD, Material.BED, Material.BOAT, Material.HOPPER, Material.HOPPER_MINECART }; + + @EventHandler + public void onPlayerCraftItem(CraftItemEvent event) + { + if (isDisabledRecipe(event.getRecipe())) + { + event.setCancelled(true); + notify(event.getWhoClicked(), "Crafting this item is disabled!"); + } + } + + private boolean isDisabledRecipe(Recipe recipe) + { + Material itemType = recipe.getResult().getType(); + + for (Material disabledRecipe : DISABLED_RECIPES) + { + if (disabledRecipe == itemType) + { + return true; + } + } + + return false; + } + + public static void notify(HumanEntity player, String message) + { + UtilPlayer.message(player, F.main("Recipes", message)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/DurabilityManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/DurabilityManager.java new file mode 100644 index 00000000..88e83ffc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/DurabilityManager.java @@ -0,0 +1,328 @@ +package mineplex.game.clans.gameplay; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemDamageEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.items.GearManager; + +public class DurabilityManager implements Listener +{ + private final Map _itemDurabilities = new HashMap<>(); + + public DurabilityManager() + { + _itemDurabilities.put(Material.DIAMOND_HELMET, 900); + _itemDurabilities.put(Material.DIAMOND_CHESTPLATE, 900); + _itemDurabilities.put(Material.DIAMOND_LEGGINGS, 900); + _itemDurabilities.put(Material.DIAMOND_BOOTS, 900); + _itemDurabilities.put(Material.DIAMOND_SWORD, 900); + _itemDurabilities.put(Material.DIAMOND_AXE, 900); + _itemDurabilities.put(Material.IRON_HELMET, 900); + _itemDurabilities.put(Material.IRON_CHESTPLATE, 900); + _itemDurabilities.put(Material.IRON_LEGGINGS, 900); + _itemDurabilities.put(Material.IRON_BOOTS, 900); + _itemDurabilities.put(Material.IRON_SWORD, 900); + _itemDurabilities.put(Material.IRON_AXE, 900); + _itemDurabilities.put(Material.CHAINMAIL_HELMET, 900); + _itemDurabilities.put(Material.CHAINMAIL_CHESTPLATE, 900); + _itemDurabilities.put(Material.CHAINMAIL_LEGGINGS, 900); + _itemDurabilities.put(Material.CHAINMAIL_BOOTS, 900); + _itemDurabilities.put(Material.GOLD_HELMET, 900); + _itemDurabilities.put(Material.GOLD_CHESTPLATE, 900); + _itemDurabilities.put(Material.GOLD_LEGGINGS, 900); + _itemDurabilities.put(Material.GOLD_BOOTS, 900); + _itemDurabilities.put(Material.GOLD_SWORD, 900); + _itemDurabilities.put(Material.GOLD_AXE, 900); + _itemDurabilities.put(Material.LEATHER_HELMET, 900); + _itemDurabilities.put(Material.LEATHER_CHESTPLATE, 900); + _itemDurabilities.put(Material.LEATHER_LEGGINGS, 900); + _itemDurabilities.put(Material.LEATHER_BOOTS, 900); + } + + private boolean canRepair(ItemStack item) + { + int repairs = ItemStackFactory.Instance.GetLoreVar(item, "Repaired", 0); + boolean canRepair = true; + + if (repairs >= 2) + { + canRepair = false; + } + + return canRepair; + } + + private int getItemDamage(ItemStack item) + { + if (item == null) + { + return 0; + } + if (_itemDurabilities.containsKey(item.getType())) + { + int defaultDurability = _itemDurabilities.get(item.getType()); + return defaultDurability - ItemStackFactory.Instance.GetLoreVar(item, "Durability", 0); + } + else + { + return item.getDurability(); + } + } + + private int itemDuraToLoreDura(ItemStack item) + { + if (item == null || !_itemDurabilities.containsKey(item.getType()) || UtilItem.isUnbreakable(item)) + { + return -1; + } + int currentDura = ItemStackFactory.Instance.GetLoreVar(item, "Durability", -1); + if (item.getDurability() == 0 && currentDura != -1) + { + return -1; + } + if (currentDura == -1) + { + updateItemDamage(item, 0, true); + return -2; + } + int newDura = (currentDura - item.getDurability()); + if (newDura <= 0) + { + return 0; + } + else + { + updateItemDamage(item, newDura, false); + item.setDurability((short)0); + } + return newDura; + } + + private void updateItemDamage(ItemStack item, int itemDamage, boolean subtractFromDefault) + { + if (item == null) + { + return; + } + if (_itemDurabilities.containsKey(item.getType())) + { + int defaultDurability = _itemDurabilities.get(item.getType()); + ItemStackFactory.Instance.SetLoreVar(item, "Durability", String.valueOf(Math.min(defaultDurability, subtractFromDefault ? (defaultDurability - itemDamage) : itemDamage))); + } + else + { + item.setDurability((short)itemDamage); + } + } + + @EventHandler + public void onDamageItem(PlayerItemDamageEvent event) + { + if (event.getItem() == null) + { + return; + } + if (_itemDurabilities.containsKey(event.getItem().getType())) + { + int damage = event.getDamage(); + int defaultDurability = _itemDurabilities.get(event.getItem().getType()); + int currentDurability = ItemStackFactory.Instance.GetLoreVar(event.getItem(), "Durability", defaultDurability); + int newDurability = currentDurability - damage; + if (newDurability > 0) + { + event.setCancelled(true); + ItemStackFactory.Instance.SetLoreVar(event.getItem(), "Durability", String.valueOf(newDurability)); + } + else + { + event.setDamage(999999); + } + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC) + { + Bukkit.getOnlinePlayers().forEach(player -> + { + boolean change = false; + for (int i = 0; i < player.getInventory().getArmorContents().length; i++) + { + int d = itemDuraToLoreDura(player.getInventory().getArmorContents()[i]); + if (d == -2) + { + change = true; + } + else if (d == 0) + { + ItemStack[] armor = new ItemStack[4]; + for (int ar = 0; ar < armor.length; ar++) + { + if (ar != i) + { + armor[ar] = player.getInventory().getArmorContents()[ar]; + } + else + { + armor[ar] = null; + } + } + player.getInventory().setArmorContents(armor); + change = true; + } + else if (d != -1) + { + change = true; + } + } + for (int i = 0; i < player.getInventory().getContents().length; i++) + { + int d = itemDuraToLoreDura(player.getInventory().getContents()[i]); + if (d == -2) + { + change = true; + } + else if (d == 0) + { + player.getInventory().setItem(i, null); + change = true; + } + else if (d != -1) + { + change = true; + } + } + + if (change) + { + UtilInv.Update(player); + } + }); + } + } + + @SuppressWarnings("deprecation") + @EventHandler + public void onRepair(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (event.getClickedBlock() == null || event.getClickedBlock().getType() != Material.ANVIL || !UtilEvent.isAction(event, ActionType.R_BLOCK) || player.isSneaking() || player.getItemInHand().getType() == Material.AIR) + { + return; + } + + if (UtilMath.offset(player.getLocation(), event.getClickedBlock().getLocation()) > 2) + { + UtilPlayer.message(player, F.main("Repair", "You are too far from the " + F.item("Anvil") + ".")); + return; + } + + ItemStack item = player.getItemInHand(); + + if (getItemDamage(item) <= 0) + { + UtilPlayer.message(player, F.main("Repair", "Your " + F.item(item == null ? ChatColor.YELLOW + "Hand" : item.getItemMeta().getDisplayName()) + " does not need repairs.")); + return; + } + + if (!UtilGear.isRepairable(item)) + { + UtilPlayer.message(player, F.main("Repair", "You cannot repair " + F.item(item.getItemMeta().getDisplayName()) + ".")); + return; + } + + if (GearManager.isCustomItem(item)) + { + UtilPlayer.message(player, F.main("Repair", "You cannot repair " + F.item(item.getItemMeta().getDisplayName()) + ".")); + return; + } + + int repairs = ItemStackFactory.Instance.GetLoreVar(item, "Repaired", 0); + boolean canRepair = canRepair(item); + + if (!canRepair) + { + UtilPlayer.message(player, F.main("Repair", "This item cannot be repaired anymore.")); + return; + } + + String creator = ItemStackFactory.Instance.GetLoreVar(item, "Owner"); + + if (creator != null) + { + if (creator.length() > 2) creator = creator.substring(2, creator.length()); + + if (!creator.equals(player.getName())) + { + UtilPlayer.message(player, F.main("Repair", "You cannot repair " + F.item(item.getItemMeta().getDisplayName()) + " by " + F.name(creator) + ".")); + return; + } + } + + if (ClansManager.getInstance().getBlockRestore().contains(event.getClickedBlock())) + { + UtilPlayer.message(player, F.main("Repair", "You cannot repair using that anvil.")); + return; + } + + // Repair! + UtilPlayer.message(player, F.main("Repair", "You repaired " + F.item(item.getItemMeta().getDisplayName()) + ".")); + updateItemDamage(item, 0, true); + UtilInv.Update(player); + + // Break + if (Math.random() > 0.85) + { + byte data = event.getClickedBlock().getData(); + if (data >= 8) // Anvil has already been damaged twice + { + player.getWorld().playEffect(event.getClickedBlock().getLocation(), Effect.STEP_SOUND, 145); + event.getClickedBlock().setType(Material.AIR); + } + else + { + event.getClickedBlock().setData((byte)(data + 4)); + } + } + + // Record + ItemStackFactory.Instance.SetLoreVar(item, "Repaired", (repairs + 1) + ""); + if (!canRepair(item)) + { + ItemMeta meta = item.getItemMeta(); + meta.getLore().add(ChatColor.BLUE + "Unrepairable"); + item.setItemMeta(meta); + } + + // Effect + player.playSound(player.getLocation(), Sound.ANVIL_USE, 1f, 1f); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java new file mode 100644 index 00000000..0dae719a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/Gameplay.java @@ -0,0 +1,836 @@ +package mineplex.game.clans.gameplay; + +import java.util.Arrays; + +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerFishEvent.State; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +import org.bukkit.event.world.StructureGrowEvent; +import org.bukkit.material.Dye; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.blockrestore.BlockRestore; +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.weight.Weight; +import mineplex.core.common.weight.WeightSet; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansWaterPlaceEvent; +import mineplex.game.clans.clans.event.IronDoorOpenEvent; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.minecraft.game.classcombat.Class.ClientClass; +import mineplex.minecraft.game.classcombat.Class.IPvpClass.ClassType; +import mineplex.minecraft.game.classcombat.Skill.event.BlockTossEvent; +import mineplex.minecraft.game.classcombat.Skill.event.BlockTossLandEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.minecraft.game.core.damage.DamageManager; + +public class Gameplay extends MiniPlugin +{ + private static final int MAX_BUILD_HEIGHT = 120; + private static final int MIN_CHEST_HEIGHT = 30; + private static final Material[] REDSTONE_TYPES = new Material[] {Material.ACTIVATOR_RAIL, Material.REDSTONE, Material.REDSTONE_BLOCK, Material.REDSTONE_COMPARATOR, Material.REDSTONE_WIRE, Material.REDSTONE_COMPARATOR_OFF, Material.REDSTONE_COMPARATOR_ON, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.REDSTONE_TORCH_OFF, Material.REDSTONE_TORCH_ON, Material.DIODE, Material.DIODE_BLOCK_OFF, Material.DIODE_BLOCK_ON, Material.DETECTOR_RAIL}; + private static final byte[] PLACED_LOG_DATA_VALUES = {12,13,14,15}; + private ClansManager _clansManager; + private BlockRestore _blockRestore; + private DamageManager _damageManager; + private WeightSet _foodDecrease; // Weighted probability sets for + // food decrease event outcomes + + public Gameplay(JavaPlugin plugin, ClansManager clansManager, BlockRestore blockRestore, DamageManager damageManager) + { + super("PvP Gameplay", plugin); + + _clansManager = clansManager; + _blockRestore = blockRestore; + _damageManager = damageManager; + _foodDecrease = new WeightSet(new Weight(10, true), new Weight(90, false)); + + // Register the custom recipes and mobs + Bukkit.getPluginManager().registerEvents(new CustomRecipes(), plugin); + Bukkit.getPluginManager().registerEvents(new CustomCreatures(), plugin); + Bukkit.getPluginManager().registerEvents(new DurabilityManager(), plugin); + } + +// @EventHandler(priority = EventPriority.LOWEST) +// public void spawnDamage(CustomDamageEvent event) +// { +// if (_clansManager.getClanUtility().getClaim(event.GetDamageeEntity().getLocation()) != null && _clansManager.getClanUtility().getClaim(event.GetDamageeEntity().getLocation()).isSafe(event.GetDamageeEntity().getLocation())) +// { +// event.SetCancelled("Safe Zone"); +// } +// } + + @EventHandler + public void stopBlockTossExploit(BlockTossLandEvent event) + { + int id = event.Entity.getBlockId(); + if (_clansManager.getClanUtility().isClaimed(event.getLocation()) + && (Material.getMaterial(id).name().endsWith("_PLATE") + || id == Material.STONE_BUTTON.getId() + || id == Material.WOOD_BUTTON.getId() + || id == Material.LEVER.getId())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerFishing(PlayerFishEvent event) + { + State state = event.getState(); + if (state == State.CAUGHT_ENTITY || state == State.CAUGHT_FISH) + { + event.setCancelled(true); + notify(event.getPlayer(), "Fishing is disabled!"); + } + } + + @EventHandler + public void onBlockToss(BlockTossEvent event) + { + Location location = event.getLocation(); + if (_clansManager.getClanUtility().isClaimed(location)) + { + event.setCancelled(true); + } + } + + @EventHandler + public void itemFrameRotate(PlayerInteractEntityEvent event) + { + if (event.getRightClicked() instanceof ItemFrame) + { + if (_clansManager.getClanUtility().isClaimed(event.getRightClicked().getLocation()) && _clansManager.getClanUtility().getClaim(event.getRightClicked().getLocation()).isSafe(event.getRightClicked().getLocation())) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onBowShoot(EntityShootBowEvent event) + { + if (event.isCancelled()) + { + return; + } + + if (event.getEntity() instanceof Player) + { + Player player = (Player) event.getEntity(); + + ClientClass playerClass = _clansManager.getClassManager().Get(player); + + if (!playerClass.IsGameClass(ClassType.Assassin, ClassType.Ranger)) + { + notify(player, "You cannot use bows without the proper class!"); + event.setCancelled(true); + } + } + } + + /** + * Decreases the hunger rate decrease speed by arbitrarily canceling a + * portion of decrease events. + * + * @param event + */ + @EventHandler(ignoreCancelled = true) + public void foodChangeLevel(FoodLevelChangeEvent event) + { + Player player = (Player) event.getEntity(); + + if (event.getFoodLevel() < player.getFoodLevel()) // Hunger is + // decreasing for + // player + { + event.setCancelled(_foodDecrease.generateRandom()); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void ObsidianCancel(BlockPlaceEvent event) + { + if (event.getBlock().getType() == Material.OBSIDIAN && event.getPlayer().getGameMode() != GameMode.CREATIVE) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place " + F.item("Obsidian") + ".")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void BedrockCancel(BlockPlaceEvent event) + { + if (event.getBlock().getType() == Material.BEDROCK && event.getPlayer().getGameMode() != GameMode.CREATIVE) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place " + F.item("Bedrock") + ".")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void BarrierCancel(BlockPlaceEvent event) + { + if (event.getBlock().getType() == Material.BARRIER && event.getPlayer().getGameMode() != GameMode.CREATIVE) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place " + F.item("Barrier Blocks") + ".")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void HopperCancel(BlockPlaceEvent event) + { + if (event.getBlock().getType() == Material.HOPPER && event.getPlayer().getGameMode() != GameMode.CREATIVE) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place " + F.item("Hoppers") + ".")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void CommandPlace(BlockPlaceEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) + { + return; + } + if (event.getBlock().getType() == Material.COMMAND || event.getBlock().getType() == Material.NOTE_BLOCK || event.getBlock().getType() == Material.REDSTONE_LAMP_ON) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place " + F.item("Proximity Devices") + ".")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void RedstoneCancel(BlockPlaceEvent event) + { + if (Arrays.asList(REDSTONE_TYPES).contains(event.getBlock().getType()) && event.getPlayer().getGameMode() != GameMode.CREATIVE) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place redstone based items.")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void MaxHeight(BlockPlaceEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) + { + return; + } + if (event.getBlock().getLocation().getBlockY() > MAX_BUILD_HEIGHT) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place blocks this high.")); + event.setCancelled(true); + } + else if(event.getBlock().getLocation().getBlockY() == (MAX_BUILD_HEIGHT - 1) && event.getBlock().getType().name().contains("DOOR") && event.getBlock().getType() != Material.TRAP_DOOR && event.getBlock().getType() != Material.IRON_TRAPDOOR) + { + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot place blocks this high.")); + event.setCancelled(true); + } + + if (event.getBlock().getLocation().getBlockY() < MIN_CHEST_HEIGHT && (event.getBlock().getType() == Material.CHEST || event.getBlock().getType() == Material.TRAPPED_CHEST || event.getBlock().getType() == Material.DISPENSER || event.getBlock().getType() == Material.DROPPER || event.getBlock().getType() == Material.FURNACE || event.getBlock().getType() == Material.BURNING_FURNACE)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void GrowTree(StructureGrowEvent event) + { + event.getBlocks().stream().filter(blockState -> blockState.getLocation().getBlockY() > MAX_BUILD_HEIGHT).forEach(blockState -> blockState.setType(Material.AIR) ); + } + + /** + * Disable all Piston related events in Clans + * + * @param event + */ + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent event) + { + event.setCancelled(true); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + public void disableEnderChest(PlayerInteractEvent event) + { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) + { + return; + } + + if (event.getClickedBlock() == null) + { + return; + } + + if (_clansManager.getWorldEvent().isInEvent(event.getClickedBlock().getLocation(), false)) + { + return; + } + + if (event.getClickedBlock().getType().equals(Material.ENDER_CHEST)) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You are not permitted to use Ender Chests.")); + event.setCancelled(true); + return; + } + } + + /** + * Disable all Piston related events in Clans + * + * @param event + */ + @EventHandler + public void onPistonRetract(BlockPistonRetractEvent event) + { + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void DispenseLiquidCancel(BlockDispenseEvent event) + { + Material material = event.getItem().getType(); + + if (material == Material.LAVA_BUCKET || material == Material.LAVA || material == Material.WATER_BUCKET || material == Material.WATER) + { + event.setCancelled(true); + } + } + + @EventHandler + public void WebBreak(BlockDamageEvent event) + { + if (event.isCancelled()) + { + return; + } + if (_clansManager.getWorldEvent().isInEvent(event.getBlock().getLocation(), false)) + { + return; + } + + if (event.getBlock().getType() == Material.WEB) + { + event.setInstaBreak(true); + } + } + + @EventHandler + public void LapisPlace(BlockPlaceEvent event) + { + if (event.isCancelled()) + { + return; + } + + if (event.getBlock().getType() != Material.LAPIS_BLOCK) + { + return; + } + + event.setCancelled(true); + + ClansWaterPlaceEvent placeEvent = new ClansWaterPlaceEvent(event.getPlayer(), event.getBlock()); + + UtilServer.CallEvent(placeEvent); + + if (placeEvent.isCancelled()) + { + return; + } + + UtilInv.remove(event.getPlayer(), Material.LAPIS_BLOCK, (byte) 0, 1); + + final Block block = event.getBlock(); + + _plugin.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable() + { + public void run() + { + block.setType(Material.WATER); + block.setData((byte) 0); + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 8); + block.getWorld().playSound(block.getLocation(), Sound.SPLASH, 2f, 1f); + } + }, 0); + } + + @EventHandler + public void EnderChestBreak(BlockBreakEvent event) + { + if (event.isCancelled()) return; + + if (event.getBlock().getType() != Material.ENDER_CHEST) return; + + event.setCancelled(true); + + event.getBlock().setTypeId(0); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation().add(0.5, 0.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.ENDER_CHEST)); + } + + @EventHandler + public void disableEnderPearls(PlayerInteractEvent event) + { + if (!isRightClick(event.getAction())) return; + + if (event.hasItem() && event.getItem().getType() == Material.ENDER_PEARL) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot use ender pearls!")); + } + } + + @EventHandler + public void disableFlintNSteel(PlayerInteractEvent event) + { + if (!isRightClick(event.getAction())) return; + + if (event.hasItem() && event.getItem().getType() == Material.FLINT_AND_STEEL) + { + event.setCancelled(true); + UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot use flint & steel!")); + } + } + + private static boolean isRightClick(Action action) + { + return action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK; + } + + @EventHandler + public void IronDoor(PlayerInteractEvent event) + { + if (event.isCancelled()) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + return; + } + + if (event.getClickedBlock().getTypeId() != 71) + { + return; + } + + Block block = event.getClickedBlock(); + + // Knock + if (event.isCancelled()) + { + if (!Recharge.Instance.use(event.getPlayer(), "Door Knock", 500, false, false)) + { + return; + } + + block.getWorld().playEffect(block.getLocation(), Effect.ZOMBIE_CHEW_WOODEN_DOOR, 0); + } + + // Open + else + { + IronDoorOpenEvent customEvent = UtilServer.CallEvent(new IronDoorOpenEvent(event.getPlayer(), block)); + + if (customEvent.isCancelled()) + { + return; + } + + if (block.getData() >= 8) block = block.getRelative(BlockFace.DOWN); + + if (block.getData() < 4) + block.setData((byte) (block.getData() + 4), true); + else + block.setData((byte) (block.getData() - 4), true); + + // Effect + block.getWorld().playEffect(block.getLocation(), Effect.DOOR_TOGGLE, 0); + } + } + + @EventHandler + public void BrewingDisable(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) return; + + if (event.getClickedBlock().getTypeId() != 117) return; + + event.setCancelled(true); + } + + @EventHandler + public void AnvilDisable(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) + return; + else if (event.getClickedBlock().getType() != Material.ANVIL) + return; + else if (player.isSneaking() && player.getItemInHand().getType() != Material.AIR) return; + + event.setCancelled(true); + } + + @EventHandler + public void BonemealCancel(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R)) return; + + Player player = event.getPlayer(); + + if (player.getItemInHand() == null) return; + + if (player.getItemInHand().getType() != Material.INK_SACK) return; + + if (player.getItemInHand().getData() == null) return; + + if (player.getItemInHand().getData().getData() != 15) return; + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void disableSaplings(BlockPlaceEvent event) + { + if (!event.getItemInHand().getType().equals(Material.SAPLING)) + { + return; + } + + Block block = event.getBlock(); + ClanInfo clan = _clansManager.getClanUtility().getClanByPlayer(event.getPlayer()); + if (clan != null) + { + ClanTerritory claim = _clansManager.getClanUtility().getClaim(block.getLocation()); + if (claim != null) + { + if (claim.Owner.equals(clan.getName())) + { + if (!Recharge.Instance.use(event.getPlayer(), "Place Sapling", 20 * 60 * 1000, true, false)) + { + event.setCancelled(true); + return; + } + } + } + } + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You can only place saplings in your own territory!")); + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void disableString(BlockPlaceEvent event) + { + if (!event.getItemInHand().getType().equals(Material.STRING)) + { + return; + } + + Block block = event.getBlock(); + ClanInfo clan = _clansManager.getClanUtility().getClanByPlayer(event.getPlayer()); + if (clan != null) + { + ClanTerritory claim = _clansManager.getClanUtility().getClaim(block.getLocation()); + if (claim != null) + { + if (claim.Owner.equals(clan.getName())) + { + return; + } + } + } + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You can only place string in your own territory!")); + event.setCancelled(true); + } + + @EventHandler + public void blockDispenser(BlockDispenseEvent event) + { + // Block bonemeal + if (event.getItem().getType() == Material.INK_SACK && ((Dye) event.getItem().getData()).getColor() == DyeColor.WHITE) + { + event.setCancelled(true); + } + + // Block flint-and-steal + if (event.getItem().getType() == Material.FLINT_AND_STEEL) + { + event.setCancelled(true); + } + + if (event.getItem().getType() == Material.FIREWORK_CHARGE) + { + event.setCancelled(true); + } + + if (event.getItem().getType() == Material.SAPLING) + { + event.setCancelled(true); + } + + if (event.getItem().getType() == Material.TNT) + { + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onLogPlace(BlockPlaceEvent event) + { + if (UtilItem.isLog(event.getBlock().getType())) + { + byte data = event.getBlock().getData(); + final byte newData; + if (data % 4 == 0) + { + newData = 12; + } + else if ((data - 1) % 4 == 0) + { + newData = 13; + } + else if ((data - 2) % 4 == 0) + { + newData = 14; + } + else if ((data - 3) % 4 == 0) + { + newData = 15; + } + else + { + newData = data; + } + + UtilServer.runSyncLater(() -> + { + event.getBlock().setData(newData); + }, 1); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.LOWEST) + public void replantTree(BlockBreakEvent event) + { + final Block block = event.getBlock(); + + if (_clansManager.getClanUtility().getClaim(block.getLocation()) != null) + { + return; + } + + if (!UtilItem.isLog(block.getType())) + { + return; + } + + if (UtilItem.isLog(block.getRelative(BlockFace.DOWN).getType())) + { + return; + } + + if (UtilItem.isLeaf(block.getRelative(BlockFace.DOWN).getType())) + { + return; + } + + if (block.getRelative(BlockFace.DOWN).getType() != Material.DIRT && block.getRelative(BlockFace.DOWN).getType() != Material.GRASS) + { + return; + } + + final byte data = block.getData(); + + if (ArrayUtils.contains(PLACED_LOG_DATA_VALUES, data)) + { + return; + } + + UtilServer.runSyncLater(() -> + { + if (block.getType() != Material.AIR) + { + return; + } + Material mat = block.getRelative(BlockFace.DOWN).getType(); + if (mat == Material.DIRT || mat == Material.GRASS) + { + block.setType(Material.SAPLING); + block.setData(data); + } + }, 20 * 10); + } + + @EventHandler + public void killRain(WeatherChangeEvent event) + { + event.setCancelled(event.toWeatherState()); + } + + @EventHandler + public void WildfireSpread(BlockBurnEvent event) + { + if (event.isCancelled()) return; + + event.setCancelled(true); + + for (int x = -1; x <= 1; x++) + { + for (int y = -1; y <= 1; y++) + { + for (int z = -1; z <= 1; z++) + { + // Self + if (x == 0 && y == 0 && z == 0) + { + event.getBlock().setType(Material.FIRE); + + if (event.getBlock().getRelative(BlockFace.DOWN).getType() == Material.GRASS) event.getBlock().getRelative(BlockFace.DOWN).setType(Material.DIRT); + + return; + } + + Block block = event.getBlock().getRelative(x, y, z); + + if (block.getRelative(BlockFace.DOWN).getType() == Material.GRASS) block.getRelative(BlockFace.DOWN).setType(Material.DIRT); + + // Surroundings + if (!((x == 0 && y == 0) || (x == 0 && z == 0) || (y == 0 && z == 0))) continue; + + if (block.getTypeId() == 0) block.setType(Material.FIRE); + } + } + } + } + + @EventHandler + public void WildfireDirt(BlockIgniteEvent event) + { + if (event.isCancelled()) return; + + if (event.getBlock().getRelative(BlockFace.DOWN).getType() == Material.GRASS) event.getBlock().getRelative(BlockFace.DOWN).setType(Material.DIRT); + } + + @EventHandler(priority = EventPriority.LOW) + public void WildfireCancel(BlockIgniteEvent event) + { + if (event.isCancelled()) return; + + if (event.getBlock().getBiome() == Biome.JUNGLE || event.getBlock().getBiome() == Biome.JUNGLE_HILLS) if (event.getCause() == IgniteCause.SPREAD) event.setCancelled(true); + } + + // @EventHandler + // public void onBlockPlace(BlockPlaceEvent event) + // { + // Location location = event.getBlock().getLocation(); + // + // if (_clansManager.getClanUtility().isNearAdminClaim(location)) + // { + // event.setCancelled(true); + // UtilPlayer.message(event.getPlayer(), F.main("Admin", "You cannot place + // blocks near admin territories!")); + // } + // } + // + // @EventHandler + // public void onBlockBreak(BlockBreakEvent event) + // { + // Location location = event.getBlock().getLocation(); + // + // if (_clansManager.getClanUtility().isNearAdminClaim(location)) + // { + // event.setCancelled(true); + // UtilPlayer.message(event.getPlayer(), F.main("Admin", "You cannot break + // blocks near admin territories!")); + // } + // } + + /* + * @EventHandler (priority = EventPriority.HIGHEST) public void + * MoneyLossSteal(CombatDeathEvent event) { if + * (!(event.GetEvent().getEntity() instanceof Player)) return; Player player + * = (Player)event.GetEvent().getEntity(); int balance = + * Clients().Get(player).Game().GetEconomyBalance(); int lose = (int) (0.04 + * * balance); //Balance + * Clients().Get(player).Game().SetEconomyBalance(balance - lose); CombatLog + * log = event.GetLog(); if (log.GetKiller() != null) { //Inform + * UtilPlayer.message(UtilPlayer.searchExact(log.GetKiller().getName()), + * F.main("Death", "You stole " + F.count((lose) + " Coins") + " from " + + * F.name(player.getName()) + ".")); //Inform UtilPlayer.message(player, + * F.main("Death", "You lost " + F.count((lose) + " Coins") + " to " + + * F.name(log.GetKiller().getName()) + ".")); } else { //Inform + * UtilPlayer.message(player, F.main("Death", "You lost " + F.count((lose) + + * " Coins") + " for dying.")); } } + */ + + @EventHandler + public void SpawnDamage(CustomDamageEvent event) + { + if (event.IsCancelled()) return; + + if (event.GetCause() != DamageCause.FALL) return; + + if (!_clansManager.getClanUtility().isSpecial(event.GetDamageeEntity().getLocation(), "Spawn")) return; + + event.SetCancelled("Spawn Fall"); + } + + public DamageManager getDamageManager() + { + return _damageManager; + } + + public static void notify(Player player, String message) + { + UtilPlayer.message(player, F.main("Clans", message)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/HiddenChestManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/HiddenChestManager.java new file mode 100644 index 00000000..6f4feb42 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/HiddenChestManager.java @@ -0,0 +1,92 @@ +package mineplex.game.clans.gameplay; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.PacketPlayOutBlockAction; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.common.util.UtilServer; +import mineplex.game.clans.clans.ClansManager; + +public class HiddenChestManager implements Listener +{ + + private final ClansManager _clansManager; + + private final Map _openChest; + + private PacketPlayOutBlockAction _lastPacket; + + public HiddenChestManager(ClansManager clansManager) + { + _clansManager = clansManager; + _openChest = new HashMap<>(); + + clansManager.getPacketHandler().addPacketHandler(packetInfo -> + { + PacketPlayOutBlockAction packet = (PacketPlayOutBlockAction) packetInfo.getPacket(); + + if (packet.equals(_lastPacket)) + { + return; + } + + // b - Action Id + // c - Action Param - How many people have the chest open + // a - Block Position + if (packet.b == 1 && packet.c > 0 && _openChest.containsValue(packet.a)) + { + packet.c--; + _lastPacket = packet; + } + }, PacketPlayOutBlockAction.class); + UtilServer.RegisterEvents(this); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onInteract(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK || !_clansManager.getIncognitoManager().Get(player).Status) + { + return; + } + + Block block = event.getClickedBlock(); + Material type = block.getType(); + + if (type != Material.CHEST && type != Material.TRAPPED_CHEST) + { + return; + } + + Location location = event.getClickedBlock().getLocation(); + _openChest.put(player, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + } + + @EventHandler + public void handleClose(InventoryCloseEvent event) + { + _openChest.remove(event.getPlayer()); + } + + @EventHandler + public void handleClose(PlayerQuitEvent event) + { + _openChest.remove(event.getPlayer()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/SafeLog.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/SafeLog.java new file mode 100644 index 00000000..48539f17 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/SafeLog.java @@ -0,0 +1,180 @@ +package mineplex.game.clans.gameplay.safelog; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +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.game.clans.clans.ClanTips.TipType; +import mineplex.game.clans.clans.freeze.ClansFreezeManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.worldevent.raid.RaidManager; +import mineplex.game.clans.gameplay.safelog.npc.NPCManager; +import mineplex.game.clans.restart.RestartManager; + +public class SafeLog extends MiniPlugin +{ + public static final long REJOIN_TIME = 60000; + + // Track Offline Players + private ClansManager _clansManager; + + public SafeLog(JavaPlugin plugin, ClansManager clansManager) + { + super("SafeLog", plugin); + + _clansManager = clansManager; + + new File(clansManager.UserDataDir).mkdir(); + } + + @Override + public void disable() + { + NPCManager.getInstance().disable(); + } + + public void onPlayerQuit(Player player) + { + boolean isSafeLog = false; + + if (_clansManager.getClanUtility().isSafe(player)) + { + isSafeLog = true; + } + + if (_flying.contains(player.getName())) + { + _flying.remove(player.getName()); + return; + } + + if (Managers.get(ClansFreezeManager.class).isFrozen(player)) + { + isSafeLog = true; + } + + if (Managers.get(ClansFreezeManager.class).isPanicking(player)) + { + isSafeLog = true; + } + + if (Managers.get(RestartManager.class).isRestarting()) + { + isSafeLog = true; + } + + if (Managers.get(RaidManager.class).isInRaid(player.getLocation())) + { + isSafeLog = true; + } + + if (_clansManager.hasTimer(player)) + { + isSafeLog = true; + } + + if (_clansManager.getIncognitoManager().Get(player).Status) + { + isSafeLog = true; + } + + if (!isSafeLog) + { + NPCManager.getInstance().spawnLogoutNpc(player); + } + } + + public void onPlayerJoin(final Player player) + { + // Despawn the player's logout NPC if they have one existing on login + if (NPCManager.getInstance().hasLogoutNpc(player)) + { + NPCManager.getInstance().despawnLogoutNpc(player); + } + + File deathFile = new File(_clansManager.UserDataDir + String.format("DEATH_%s.dat", player.getUniqueId().toString())); + + if (deathFile.exists()) + { + try + { + DataInputStream stream = new DataInputStream(new FileInputStream(deathFile)); + + final long time = stream.readLong(); + final int length = stream.readInt(); + final StringBuilder killerName = new StringBuilder(); + + for (int i = 0; i < length; i++) + { + killerName.append((char) stream.readByte()); + } + + stream.close(); + + UtilServer.getServer().getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> + { + _clansManager.ClanTips.displayTip(TipType.NPC_RIPPARONI, player); + UtilPlayer.message(player, F.main("SafeLog", "You were killed by " + F.elem(killerName) + " when you logged out! This happened about " + F.time(UtilTime.MakeStr(System.currentTimeMillis() - time))) + " ago."); + UtilTextMiddle.display("Offline Death", "Log out in a safer place next time!", 15, 80, 40, player); + }, 15); + + deathFile.delete(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + + private List _flying = new ArrayList<>(); + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerQuit(PlayerQuitEvent event) + { + onPlayerQuit(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void flyCheck(PlayerKickEvent event) + { + if (event.getPlayer().getItemInHand() != null && event.getPlayer().getItemInHand().getItemMeta() != null && (C.cGold + "Wind Blade").equals(event.getPlayer().getItemInHand().getItemMeta().getDisplayName())) + if (event.getReason().contains("flying is not enabled")) + _flying.add(event.getPlayer().getName()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerKicked(PlayerKickEvent event) + { + if (event.isCancelled()) return; + if (event.getPlayer().getItemInHand() != null && event.getPlayer().getItemInHand().getItemMeta() != null && (C.cGold + "Wind Blade").equals(event.getPlayer().getItemInHand().getItemMeta().getDisplayName())) + if (event.getReason().contains("flying is not enabled")) + return; + + onPlayerQuit(event.getPlayer()); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + onPlayerJoin(event.getPlayer()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java new file mode 100644 index 00000000..4dfa74bd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/CombatLogNPC.java @@ -0,0 +1,224 @@ +package mineplex.game.clans.gameplay.safelog.npc; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +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.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; +import mineplex.game.clans.clans.ClansManager; + +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 CraftLivingEntity _lastDamager; + + private String _userDataPath; + + public int getEntityId() + { + return _npc.getEntityId(); + } + + public CombatLogNPC(Player player, DisguiseManager disguiseManager, HologramManager hologramManager, boolean wasCreative, String userDataPath) + { + _playerInfo = new PlayerInfo(player); + _creative = wasCreative; + _userDataPath = userDataPath; + + _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) + { + _npc.remove(); + _npc = null; + _hologram.stop(); + _hologram = null; + } + } + + public void remove() + { + _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(ClansManager.getInstance().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 inRange = UtilPlayer.getNearby(spawnLoc, 75d); + + // Disguise + DisguisePlayer disguise = new DisguisePlayer(skel, ((CraftPlayer) player).getHandle().getProfile()); + _disguiseManager.disguise(disguise, attempted -> inRange.contains(attempted)); + + _hologram.setFollowEntity(skel); + + return skel; + } + + public boolean wasCreative() + { + return _creative; + } + + public CraftLivingEntity getLastDamager() + { + return _lastDamager; + } + + public void setLastDamager(CraftLivingEntity damager) + { + _lastDamager = damager; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java new file mode 100644 index 00000000..ef71f42d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/NPCManager.java @@ -0,0 +1,259 @@ +package mineplex.game.clans.gameplay.safelog.npc; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +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.world.ChunkUnloadEvent; +import org.bukkit.metadata.FixedMetadataValue; + +import mineplex.core.MiniPlugin; +import mineplex.core.hologram.HologramManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.spawn.Spawn; +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 ClansManager _clansManager; + private Set _logoutNpcs; + private Set _toKillIds; + + private HologramManager _hologramManager; + + public NPCManager(ClansManager plugin, HologramManager hologramManager) + { + super("NPC Manager", plugin.getPlugin()); + + _instance = this; + _logoutNpcs = new HashSet<>(); + _toKillIds = new HashSet<>(); + _clansManager = plugin; + _hologramManager = hologramManager; + } + + @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 (!hasLogoutNpc(player)) + { + CombatLogNPC npc = new CombatLogNPC(player, _clansManager.getDisguiseManager(), _hologramManager, player.getGameMode().equals(GameMode.CREATIVE), _clansManager.UserDataDir); + 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 : Spawn.getSpawnWorld().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) + { + ClanInfo clan = _clansManager.getClan(event.GetDamagerPlayer(true)); + + if (clan != null && clan.isMember(logoutNpc.getPlayerInfo().getUniqueId())) + { + event.SetCancelled("Cannot hurt clan member."); + return; + } + + 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 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(); + } + + 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; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java new file mode 100644 index 00000000..69a138d6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/npc/PlayerInfo.java @@ -0,0 +1,82 @@ +package mineplex.game.clans.gameplay.safelog.npc; + +import java.util.HashSet; +import java.util.Set; +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; + +public class PlayerInfo +{ + private String _playerName; + private UUID _playerUuid; + private Set _items; + + public PlayerInfo(Player player) + { + _playerName = player.getName(); + _playerUuid = player.getUniqueId(); + _items = fetchItems(player.getInventory()); + } + + public void dropItems(Location location) + { + World world = location.getWorld(); + for (ItemStack item : _items) + { + world.dropItemNaturally(location, item); + } + } + + public String getPlayerName() + { + return _playerName; + } + + public Set getItems() + { + return _items; + } + + public UUID getUniqueId() + { + return _playerUuid; + } + + public String getPlayerUuid() + { + return _playerUuid.toString(); + } + + public Player getPlayer() + { + return Bukkit.getPlayerExact(_playerName); + } + + private Set fetchItems(PlayerInventory inventory) + { + Set items = new HashSet(); + + addItems(items, inventory.getArmorContents()); + addItems(items, inventory.getContents()); + + return items; + } + + private void addItems(Set items, ItemStack[] itemsToAdd) + { + for (ItemStack item : itemsToAdd) + { + if (item != null && item.getType() != Material.AIR) + { + items.add(item); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java new file mode 100644 index 00000000..1da80b4e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java @@ -0,0 +1,220 @@ +package mineplex.game.clans.items; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.common.util.UtilInv; +import mineplex.game.clans.items.attributes.AttributeContainer; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +/** + * Represents a customizable wrapper for an {@link ItemStack}, enabling the + * possession of special abilities, attributes, and triggers on item. + */ +public class CustomItem +{ + // Chat color used for item display name + private static final ChatColor TITLE_COLOR = ChatColor.GOLD; + // Chat color used for attribute descriptions + private static final ChatColor ATTRIBUTE_COLOR = ChatColor.WHITE; + + protected transient String _displayName; + protected transient String[] _description; + protected transient Material _material; + + protected transient Player _lastUser = null; + + private AttributeContainer _attributes; + + protected String _uuid; + + protected boolean _dullEnchantment; + + public String OriginalOwner = null; + + public String getUUID() + { + return _uuid; + } + + public CustomItem(String displayName, String[] description, Material material) + { + _displayName = displayName; + _description = description; + _material = material; + _attributes = new AttributeContainer(); + _uuid = UUID.randomUUID().toString(); + } + + public CustomItem(Material material) + { + this(prettifyName(material), null, material); + } + + /** + * @return the name displayed to players for the item. + */ + public String getDisplayName() + { + return ChatColor.RESET.toString() + TITLE_COLOR + _attributes.formatItemName(_displayName); + } + + public String[] getDescription() + { + return _description; + } + + public List getLore() + { + List lore = new ArrayList(); + + if (getDescription() != null) + { + for (String desc : getDescription()) + { + lore.add(ATTRIBUTE_COLOR + desc); + } + } + + // Display attribute descriptions and stats in lore + for (ItemAttribute attribute : _attributes.getAttributes()) + { + String attributeLine = ATTRIBUTE_COLOR + "• " + attribute.getDescription(); + lore.add(attributeLine); + } + + return lore; + } + + public ItemStack toItemStack(int amount) + { + ItemStack item = CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(new ItemStack(_material, amount))); + update(item); + + if (_dullEnchantment) + { + UtilInv.addDullEnchantment(item); + } + + return item; + } + + public ItemStack toItemStack() + { + return toItemStack(1); + } + + public void addDullEnchantment() + { + _dullEnchantment = true; + } + + public void removeDullEnchantment() + { + _dullEnchantment = false; + } + + public void onInteract(PlayerInteractEvent event) + { + for (ItemAttribute attribute : _attributes.getAttributes()) + { + attribute.onInteract(event); + } + } + + public void onAttack(CustomDamageEvent event) + { + for (ItemAttribute attribute : _attributes.getAttributes()) + { + attribute.onAttack(event); + } + } + + public void onAttacked(CustomDamageEvent event) + { + for (ItemAttribute attribute : _attributes.getAttributes()) + { + attribute.onAttacked(event); + } + } + + /** + * @param item - the item to check for a matching link + * @return true, if {@code item} matches this CustomItem via UUID, false + * otherwise. + */ + public boolean matches(CustomItem item) + { + return item.getUUID().equals(_uuid); + } + + /** + * Update {@code item} with the proper meta properties suited for this + * {@link CustomItem}. + * + * @param item - the item whose meta properties are being updated to become + * a version of this updated custom item. + */ + public void update(ItemStack item) + { + ItemMeta meta = item.getItemMeta(); + + String displayName = getDisplayName(); + List lore = getLore(); + + meta.setDisplayName(displayName); + meta.setLore(lore); + + item.setItemMeta(meta); + + if (_dullEnchantment) + { + UtilInv.addDullEnchantment(item); + } + + GearManager.writeNBT(this, item); + } + + public static String prettifyName(Material material) + { + String name = ""; + String[] words = material.toString().split("_"); + + for (String word : words) + { + word = word.toLowerCase(); + name += word.substring(0, 1).toUpperCase() + word.substring(1) + " "; + } + + return name.trim(); + } + + public Material getMaterial() + { + return _material; + } + + public AttributeContainer getAttributes() + { + return _attributes; + } + + public void setMaterial(Material material) + { + if (_material == null) + { + _displayName = prettifyName(material); + } + _material = material; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java new file mode 100644 index 00000000..87c8585e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java @@ -0,0 +1,764 @@ +package mineplex.game.clans.items; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.weight.Weight; +import mineplex.core.common.weight.WeightSet; +import mineplex.core.donation.DonationManager; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.packethandler.PacketInfo; +import mineplex.game.clans.items.attributes.AttributeContainer; +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.attributes.armor.ConqueringArmorAttribute; +import mineplex.game.clans.items.attributes.armor.LavaAttribute; +import mineplex.game.clans.items.attributes.armor.PaddedAttribute; +import mineplex.game.clans.items.attributes.armor.ReinforcedAttribute; +import mineplex.game.clans.items.attributes.armor.SlantedAttribute; +import mineplex.game.clans.items.attributes.bow.HeavyArrowsAttribute; +import mineplex.game.clans.items.attributes.bow.HuntingAttribute; +import mineplex.game.clans.items.attributes.bow.InverseAttribute; +import mineplex.game.clans.items.attributes.bow.LeechingAttribute; +import mineplex.game.clans.items.attributes.bow.RecursiveAttribute; +import mineplex.game.clans.items.attributes.bow.ScorchingAttribute; +import mineplex.game.clans.items.attributes.bow.SlayingAttribute; +import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute; +import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; +import mineplex.game.clans.items.attributes.weapon.FrostedAttribute; +import mineplex.game.clans.items.attributes.weapon.HasteAttribute; +import mineplex.game.clans.items.attributes.weapon.JaggedAttribute; +import mineplex.game.clans.items.attributes.weapon.SharpAttribute; +import mineplex.game.clans.items.commands.GearCommand; +import mineplex.game.clans.items.commands.RuneCommand; +import mineplex.game.clans.items.economy.GoldToken; +import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.DemonicScythe; +import mineplex.game.clans.items.legendaries.GiantsBroadsword; +import mineplex.game.clans.items.legendaries.HyperAxe; +import mineplex.game.clans.items.legendaries.KnightLance; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.game.clans.items.legendaries.MagneticMaul; +import mineplex.game.clans.items.legendaries.MeridianScepter; +import mineplex.game.clans.items.legendaries.WindBlade; +import mineplex.game.clans.items.rares.RareItem; +import mineplex.game.clans.items.rares.RunedPickaxe; +import mineplex.game.clans.items.runes.RuneManager; +import mineplex.game.clans.items.smelting.SmeltingListener; +import mineplex.game.clans.items.ui.GearShop; +import mineplex.serverdata.serialization.RuntimeTypeAdapterFactory; +import net.minecraft.server.v1_8_R3.NBTBase; +import net.minecraft.server.v1_8_R3.NBTTagByte; +import net.minecraft.server.v1_8_R3.NBTTagCompound; +import net.minecraft.server.v1_8_R3.NBTTagString; +import net.minecraft.server.v1_8_R3.Packet; +import net.minecraft.server.v1_8_R3.PacketPlayOutSetSlot; +import net.minecraft.server.v1_8_R3.PacketPlayOutWindowItems; +/** + * Handles converting legendary itemstacks to their respective CustomItem objects + */ +public class GearManager extends MiniPlugin implements IPacketHandler, Runnable +{ + public enum Perm implements Permission + { + RUNE_COMMAND, + GEAR_COMMAND, + } + + private static final String ITEM_SERIALIZATION_TAG = "-JSON-"; + private static final Gson GSON; + + // Weightings for randomly selecting number of attributes (1, 2, 3) + private static final WeightSet ATTRIBUTE_WEIGHTS = new WeightSet( + new Weight<>(3, 3), + new Weight<>(20, 2), + new Weight<>(77, 1) + ); + + // Weightings for randomly selecting item type (legendary/weapon/armor/bow) + private static final WeightSet TYPE_WEIGHTS = new WeightSet( + new Weight<>(9, ItemType.LEGENDARY), + new Weight<>(9, ItemType.RARE), + new Weight<>(34, ItemType.ARMOR), + new Weight<>(25, ItemType.WEAPON), + new Weight<>(23, ItemType.BOW) + ); + + private static final WeightSet> LEGENDARY_WEIGHTS = new WeightSet<>( + MeridianScepter.class, + AlligatorsTooth.class, + WindBlade.class, + GiantsBroadsword.class, + HyperAxe.class, + MagneticMaul.class, + KnightLance.class + ); + + private static final WeightSet> RARE_WEIGHTS = new WeightSet<>( + RunedPickaxe.class + ); + + private static final WeightSet WEAPON_TYPES = new WeightSet<>( + Material.DIAMOND_SWORD, + Material.GOLD_SWORD, + Material.IRON_SWORD, + Material.DIAMOND_AXE, + Material.GOLD_AXE, + Material.IRON_AXE + ); + + private static final WeightSet ARMOR_TYPES = new WeightSet<>( + Material.DIAMOND_HELMET, + Material.DIAMOND_CHESTPLATE, + Material.DIAMOND_LEGGINGS, + Material.DIAMOND_BOOTS, + Material.IRON_HELMET, + Material.IRON_CHESTPLATE, + Material.IRON_LEGGINGS, + Material.IRON_BOOTS, + Material.GOLD_HELMET, + Material.GOLD_CHESTPLATE, + Material.GOLD_LEGGINGS, + Material.GOLD_BOOTS + ); + + private static final WeightSet> WEAPON_ATTRIBUTES = new WeightSet<>( + FrostedAttribute.class, + SharpAttribute.class, + JaggedAttribute.class, + HasteAttribute.class, + FlamingAttribute.class, + ConqueringAttribute.class + ); + + private static final WeightSet> ARMOR_ATTRIBUTES = new WeightSet<>( + SlantedAttribute.class, + ReinforcedAttribute.class, + ConqueringArmorAttribute.class, + PaddedAttribute.class, + LavaAttribute.class + ); + + private static final WeightSet> BOW_ATTRIBUTES = new WeightSet<>( + HeavyArrowsAttribute.class, + HuntingAttribute.class, + InverseAttribute.class, + LeechingAttribute.class, + RecursiveAttribute.class, + ScorchingAttribute.class, + SlayingAttribute.class + ); + + // Attribute Masks + private static final EnumSet MASK_ATTRIBUTES = EnumSet.of( + Material.GOLD_RECORD, + Material.GREEN_RECORD, + Material.RECORD_3, + Material.RECORD_4, + Material.RECORD_5, + Material.RECORD_6, + Material.RECORD_7, + Material.RECORD_8, + Material.RECORD_9, + Material.RECORD_10, + Material.RECORD_11, + Material.RECORD_12, + Material.RABBIT_FOOT + ); + + static + { + // Initialize attribute types factory for JSON handling of polymorphism. + RuntimeTypeAdapterFactory attributeFactory = RuntimeTypeAdapterFactory.of(ItemAttribute.class); + ARMOR_ATTRIBUTES.elements().forEach(attributeFactory::registerSubtype); + WEAPON_ATTRIBUTES.elements().forEach(attributeFactory::registerSubtype); + BOW_ATTRIBUTES.elements().forEach(attributeFactory::registerSubtype); + + // Initialize legendary item type factory for JSON handling of polymorphism. + RuntimeTypeAdapterFactory customItemType = RuntimeTypeAdapterFactory.of(CustomItem.class); + customItemType.registerSubtype(CustomItem.class); + customItemType.registerSubtype(LegendaryItem.class); + customItemType.registerSubtype(RareItem.class); + customItemType.registerSubtype(GoldToken.class); + LEGENDARY_WEIGHTS.elements().forEach(customItemType::registerSubtype); + RARE_WEIGHTS.elements().forEach(customItemType::registerSubtype); + customItemType.registerSubtype(DemonicScythe.class); + + // Build GSON instance off factories for future serialization of items. + GSON = new GsonBuilder().registerTypeAdapterFactory(attributeFactory).registerTypeAdapterFactory(customItemType).create(); + } + + private static Map _customItemCache = new HashMap<>(); + private static GearManager _instance; // Singleton instance + + // Mapping of player names (key) to cached gear set (value). + private Map _playerGears = new HashMap<>(); + + private GearShop _shop; + private RuneManager _rune; + + public GearManager(JavaPlugin plugin, PacketHandler packetHandler, CoreClientManager clientManager, DonationManager donationManager) + { + super("CustomGear", plugin); + + if (_instance != null) + { + throw new RuntimeException("GearManager is already initialized"); + } + + _instance = this; + + _shop = new GearShop(this, clientManager, donationManager); + _rune = new RuneManager("Rune", plugin); + + // Register listeners + UtilServer.getServer().getPluginManager().registerEvents(new ItemListener(getPlugin()), getPlugin()); + UtilServer.getServer().getPluginManager().registerEvents(new SmeltingListener(), getPlugin()); + + packetHandler.addPacketHandler(this, PacketPlayOutSetSlot.class, PacketPlayOutWindowItems.class); + + plugin.getServer().getScheduler().runTaskTimer(plugin, this, 1L, 1L); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.RUNE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.GEAR_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new GearCommand(this)); + addCommand(new RuneCommand(this)); + } + + public RuneManager getRuneManager() + { + return _rune; + } + + /** + * Tick & update internal logic for {@link GearManager}. Called once per tick. + */ + @Override + public void run() + { + Iterator iterator = _playerGears.values().iterator(); + while (iterator.hasNext()) + { + PlayerGear gear = iterator.next(); + if (gear.cleanup()) + { + iterator.remove(); + } + else + { + gear.update(); + } + } + } + + /** + * @param player - the player whose {@link PlayerGear} set is to be fetched. + * @return the cached or newly instantiated {@link PlayerGear} associated + * with {@code player}. + */ + public PlayerGear getPlayerGear(Player player) + { + return _playerGears.computeIfAbsent(player, PlayerGear::new); + } + + public Set> getFindableLegendaries() + { + return LEGENDARY_WEIGHTS.elements(); + } + + public Set> getArmorAttributes() + { + return ARMOR_ATTRIBUTES.elements(); + } + + public Set> getBowAttributes() + { + return BOW_ATTRIBUTES.elements(); + } + + public Set> getWeaponAttributes() + { + return WEAPON_ATTRIBUTES.elements(); + } + + public CustomItem generateItem() + { + int attributeCount = ATTRIBUTE_WEIGHTS.generateRandom(); + ItemType itemType = TYPE_WEIGHTS.generateRandom(); + + RareItemFactory factory = RareItemFactory.begin(itemType); + + if (itemType == ItemType.RARE) + { + factory.setRare(RARE_WEIGHTS.generateRandom()); + } + else if (itemType == ItemType.LEGENDARY) + { + factory.setLegendary(LEGENDARY_WEIGHTS.generateRandom()); + } + else if (itemType == ItemType.ARMOR) + { + factory.setType(ARMOR_TYPES.generateRandom()); + } + else if (itemType == ItemType.WEAPON) + { + factory.setType(WEAPON_TYPES.generateRandom()); + } + else if (itemType == ItemType.BOW) + { + factory.setType(Material.BOW); + } + + if (itemType != ItemType.LEGENDARY || (UtilMath.random.nextDouble() <= .35 && factory.getMaterial() != Material.RECORD_6)) // Melee Legendaries have a chance to spawn with attributes + { + AttributeContainer attributes = new AttributeContainer(); + generateAttributes(attributes, itemType, attributeCount); + + System.out.println("Generating attributes..."); + System.out.println("Remaining size: " + attributes.getRemainingTypes().size()); + + if (attributes.getSuperPrefix() != null) + { + System.out.println("Set super prefix: " + attributes.getSuperPrefix().getClass()); + factory.setSuperPrefix(attributes.getSuperPrefix().getClass()); + } + if (attributes.getPrefix() != null) + { + System.out.println("Set prefix: " + attributes.getPrefix().getClass()); + factory.setPrefix(attributes.getPrefix().getClass()); + } + if (attributes.getSuffix() != null) + { + System.out.println("Set suffix: " + attributes.getSuffix().getClass()); + factory.setSuffix(attributes.getSuffix().getClass()); + } + } + + return factory.getWrapper(); + } + + public void generateAttributes(AttributeContainer container, ItemType type, int count) + { + for (int i = 0; i < count; i++) + { + int attempts = 0; + Set remaining = container.getRemainingTypes(); + ItemAttribute attribute = null; + + while (remaining.size() > 0 && attempts < 10 && attribute == null) + { + ItemAttribute sampleAttribute = null; + + switch (type) + { + case ARMOR: + sampleAttribute = instantiate(ARMOR_ATTRIBUTES.generateRandom()); + break; + case WEAPON: + sampleAttribute = instantiate(WEAPON_ATTRIBUTES.generateRandom()); + break; + case LEGENDARY: + sampleAttribute = instantiate(WEAPON_ATTRIBUTES.generateRandom()); + break; + case BOW: + sampleAttribute = instantiate(BOW_ATTRIBUTES.generateRandom()); + break; + default: + break; + } + + if (sampleAttribute != null && remaining.contains(sampleAttribute.getType())) + { + attribute = sampleAttribute; // Select valid attribute to add + } + + attempts++; + } + + if (attribute != null) + { + container.addAttribute(attribute); + } + } + } + + public void spawnItem(Location location) + { + CustomItem item = generateItem(); + if (item.getMaterial() == Material.RECORD_4 || item.getMaterial() == Material.GOLD_RECORD || item.getMaterial() == Material.RECORD_3 || item.getMaterial() == Material.RECORD_5 || item.getMaterial() == Material.RECORD_6 || item.getMaterial() == Material.GREEN_RECORD || item.getMaterial() == Material.RECORD_12) + { + UtilFirework.playFirework(location, Type.BALL, Color.RED, true, false); + } + else + { + UtilFirework.playFirework(location, Type.BALL, Color.AQUA, true, false); + } + location.getWorld().dropItem(location, item.toItemStack()); + } + + public static CustomItem parseItem(ItemStack item) + { + if (item == null) + { + return null; + } + Map data = getUnhandledTags(item); + if (data == null) + { + return null; + } + if (data.containsKey("gearmanager.uuid")) + { + String strUUID = ((NBTTagString) data.get("gearmanager.uuid")).a_(); + try + { + UUID uuid = UUID.fromString(strUUID); + CustomItem customItem = _customItemCache.get(uuid); + if (customItem == null) + { + String json = ((NBTTagString) data.get("gearmanager.json")).a_(); + customItem = deserialize(json); + _customItemCache.put(uuid, customItem); + } + return customItem; + } + // Not an UUID? + catch (IllegalArgumentException exception) + { + if (!data.containsKey("gearmanager.warnuuid")) + { + // Add to the lore that this item is corrupted + List lore = item.getItemMeta().getLore(); + lore.add(""); + lore.add(C.cRedB + "Corrupted item (Error 1)"); + data.put("gearmanager.warnuuid", new NBTTagByte((byte) 1)); + exception.printStackTrace(); + saveUnhandledTags(item, data); + } + return null; + } + // Failed to parse + catch (JsonSyntaxException exception) + { + if (!data.containsKey("gearmanager.warnsyntax")) + { + // Add to the lore that this item is corrupted + List lore = item.getItemMeta().getLore(); + lore.add(""); + lore.add(C.cRedB + "Corrupted item (Error 2)"); + data.put("gearmanager.warnsyntax", new NBTTagByte((byte) 1)); + System.out.println(((NBTTagString) data.get("gearmanager.json")).a_()); + exception.printStackTrace(); + saveUnhandledTags(item, data); + } + return null; + } + // Other + catch (Exception exception) + { + if (!data.containsKey("gearmanager.warnother")) + { + // Add to the lore that this item is corrupted + List lore = item.getItemMeta().getLore(); + lore.add(""); + lore.add(C.cRedB + "Corrupted item (Error 3)"); + data.put("gearmanager.warnother", new NBTTagByte((byte) 1)); + exception.printStackTrace(); + saveUnhandledTags(item, data); + } + return null; + } + } + + return null; + } + + public static void writeNBT(CustomItem customItem, ItemStack item) + { + Map data = getUnhandledTags(item); + data.put("gearmanager.uuid", new NBTTagString(customItem._uuid)); + data.put("gearmanager.json", new NBTTagString(serialize(customItem))); + saveUnhandledTags(item, data); + } + + public static boolean isCustomItem(ItemStack item) + { + Map data = getUnhandledTags(item); + if (data.containsKey("gearmanager.uuid") && data.containsKey("gearmanager.json")) + { + return true; + } + + return false; + } + + /** + * @param type - the class-type of the object to be instantiated. (must have + * zero-argument constructor) + * @return a newly instantiated instance of {@code type} class-type. + * Instantied with zero argument constructor. + */ + private static T instantiate(Class type) + { + try + { + return type.newInstance(); + } + catch (Exception e) + { + return null; + } + } + + public static String serialize(CustomItem customItem) + { + return GSON.toJson(customItem, CustomItem.class); + } + + public static CustomItem deserialize(String serialization) + { + return GSON.fromJson(serialization, CustomItem.class); + } + + /** + * @return singleton instance of {@link GearManager}. + */ + public static GearManager getInstance() + { + return _instance; + } + + /** + * @param player - the player to see if they should have their out-going + * packets masked on CustomGear items. + * @return true, if the player should have their gear lore masked, false + * otherwise. + */ + private boolean maskGearPacket(Player player) + { + return player.getGameMode() != GameMode.CREATIVE; + } + + public void handle(PacketInfo packetInfo) + { + // Don't mask custom gear lore for creative players, as this will break them. + // To be precise, the lore is added more than once because the creative client spawns in new items with the existing lore + // fixme + if (!maskGearPacket(packetInfo.getPlayer())) return; + + Packet packet = packetInfo.getPacket(); + + if (packet instanceof PacketPlayOutSetSlot) + { + PacketPlayOutSetSlot slotPacket = (PacketPlayOutSetSlot) packet; + slotPacket.c = maskItem(slotPacket.c, packetInfo.getPlayer()); // Mask all out-going item packets + } + else if (packet instanceof PacketPlayOutWindowItems) + { + PacketPlayOutWindowItems itemsPacket = (PacketPlayOutWindowItems) packet; + + for (int i = 0; i < itemsPacket.b.length; i++) + { + itemsPacket.b[i] = maskItem(itemsPacket.b[i], packetInfo.getPlayer()); // Mask all out-going item packets + ItemStack item = CraftItemStack.asCraftMirror(itemsPacket.b[i]); + if (item != null && MASK_ATTRIBUTES.contains(item.getType())) + itemsPacket.b[i] = removeAttributes(itemsPacket.b[i]); + } + } + } + + private net.minecraft.server.v1_8_R3.ItemStack removeAttributes(net.minecraft.server.v1_8_R3.ItemStack item) + { + if (item == null) return null; + + if (item.getTag() == null) + { + item.setTag(new NBTTagCompound()); + } + + item.getTag().setInt("HideFlags", 62); + + return item; + } + + private net.minecraft.server.v1_8_R3.ItemStack maskItem(net.minecraft.server.v1_8_R3.ItemStack item, Player player) + { + // Cannot mask a null item + if (item == null) + { + return null; + } + + CraftItemStack originalItem = CraftItemStack.asCraftMirror(item.cloneItemStack()); + ItemMeta originalMeta = originalItem.getItemMeta(); + + // No need to modify item packets with no lore + if (originalMeta == null || originalMeta.getLore() == null) + { + return item; + } + + List newLore = cleanseLore(originalMeta.getLore()); + + CustomItem ci = parseItem(originalItem); + + if (ci != null && LEGENDARY_WEIGHTS.elements().contains(ci.getClass())) + { + String originalOwner = null; + if (ci.OriginalOwner == null) + { + originalOwner = "You"; + } + else + { + if (player.getUniqueId().toString().equals(ci.OriginalOwner)) + { + originalOwner = "You"; + } + else + { + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(ci.OriginalOwner)); + originalOwner = offlinePlayer.getName(); + } + } + newLore.add(" "); + newLore.add(C.cWhite + "Original Owner: " + C.cYellow + originalOwner); + } + if (ci != null) + { + newLore.add(" "); + newLore.add(C.cWhite + "UUID: " + C.cYellow + ci._uuid); + } + + net.minecraft.server.v1_8_R3.ItemStack newItem = CraftItemStack.asNMSCopy(originalItem); + CraftItemStack newCopy = CraftItemStack.asCraftMirror(newItem); + ItemMeta newMeta = newCopy.getItemMeta(); + newMeta.setLore(newLore); + newCopy.setItemMeta(newMeta); + return newItem; + } + + private List cleanseLore(List input) + { + List cleansed = new ArrayList<>(); + for (String s : input) + { + if (!s.startsWith(ITEM_SERIALIZATION_TAG)) + { + cleansed.add(s); + } + } + return cleansed; + } + + public void openShop(Player player) + { + _shop.attemptShopOpen(player); + } + + // WARNING + // This will not be persistent if the ItemStack is a block and placed then picked up + private static Map getUnhandledTags(ItemStack itemStack) + { + net.minecraft.server.v1_8_R3.ItemStack handle = ((CraftItemStack) itemStack).getHandle(); + if (handle == null) + return Collections.emptyMap(); + + NBTTagCompound tag = handle.getTag(); + + if (tag == null) + return Collections.emptyMap(); + + Map unhandled = new HashMap<>(); + for (String name : tag.c()) + { + unhandled.put(name, tag.get(name)); + } + return unhandled; + } + + private static void saveUnhandledTags(ItemStack itemStack, Map map) + { + net.minecraft.server.v1_8_R3.ItemStack handle = ((CraftItemStack) itemStack).getHandle(); + NBTTagCompound tag = handle.getTag(); + + if (tag != null) + { + for (String name : map.keySet()) + { + tag.set(name, map.get(name)); + } + } + } + + public static void save(ItemStack itemStack, boolean remove) + { + CustomItem item = parseItem(itemStack); + if (item != null) + { + Map data = getUnhandledTags(itemStack); + data.put("gearmanager.json", new NBTTagString(serialize(item))); + saveUnhandledTags(itemStack, data); + if (remove) + { + _customItemCache.remove(UUID.fromString(item._uuid)); + } + } + } + + public static void cleanup() + { + Iterator it = _customItemCache.values().iterator(); + while (it.hasNext()) + { + CustomItem item = it.next(); + if (item._lastUser == null || !item._lastUser.isOnline()) + { + it.remove(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java new file mode 100644 index 00000000..8b1fa0bd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java @@ -0,0 +1,266 @@ +package mineplex.game.clans.items; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.java.JavaPlugin; + +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.UtilServer; +import mineplex.game.clans.clans.invsee.InvseeModifyOnlineInventoryEvent; +import mineplex.game.clans.items.attributes.AttributeContainer; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +/** + * Listens for item-related trigger events and accordingly triggers appropriate + * {@link PlayerGear} events for {@link CustomItem} abilities and attributes. + * + * @author MrTwiggy + */ +public class ItemListener implements Listener, Runnable +{ + private static final String PROJECTILE_META_TAG = "[CustomGearProj]"; + + private JavaPlugin _plugin; + + public ItemListener(JavaPlugin plugin) + { + _plugin = plugin; + _plugin.getServer().getScheduler().runTaskTimer(_plugin, this, 0, 20 * 60 * 5); + } + + @Override + public void run() + { + for (Player player : UtilServer.getPlayersCollection()) + { + save(player, false); + } + GearManager.cleanup(); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void on(PlayerQuitEvent event) + { + save(event.getPlayer(), true); + } + + private void save(Player player, boolean remove) + { + for (ItemStack item : UtilInv.getItemsUncloned(player)) + { + GearManager.save(item, remove); + } + } + + /** + * Handle the trigger of custom gear related effects and abilities. + * + * @param event + */ + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerAttack(CustomDamageEvent event) + { + if (event.IsCancelled()) return; // Checks for Pre-Cancelled event and stops + + Player damager = event.GetDamagerPlayer(false); // For non-ranged attacks + Player damagee = event.GetDamageePlayer(); + Projectile projectile = event.GetProjectile(); + + // Trigger custom gear effects for attacker melee weapons + if (damager != null && event.GetCause() == DamageCause.ENTITY_ATTACK) + { + PlayerGear attackerGear = getGear(damager); + attackerGear.onAttack(event); + } + + // Trigger custom gear effects for defender armor + if (damagee != null) + { + PlayerGear defenderGear = getGear(damagee); + defenderGear.onAttacked(event); + } + + // Trigger bow-related attribute effects properly + if (projectile != null) + { + if (projectile.hasMetadata(PROJECTILE_META_TAG)) + { + for (MetadataValue data : projectile.getMetadata(PROJECTILE_META_TAG)) + { + AttributeContainer container = (AttributeContainer) data.value(); + + for (ItemAttribute attribute : container.getAttributes()) + { + attribute.onAttack(event); + } + } + } + } + } + + /** + * Properly marks projectiles shot from a custom-gear bow so that it will properly trigger events. + * + * @param event + */ + @EventHandler + public void onEntityShootBow(EntityShootBowEvent event) + { + if (event.getEntity() instanceof Player) + { + Player player = (Player) event.getEntity(); + PlayerGear gear = getGear(player); + + CustomItem weapon = gear.getWeapon(); + + if (weapon != null) + { + // Copy weapon attributes onto projectile for later processing + AttributeContainer attributes = weapon.getAttributes(); + + Entity projectile = event.getProjectile(); + projectile.setMetadata(PROJECTILE_META_TAG, new FixedMetadataValue(_plugin, attributes)); + } + } + } + + /** + * Handle weapon ability activation of custom gear. + * + * @param event + */ + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) + { + // Activate weapon interact abilities + PlayerGear playerGear = getGear(event.getPlayer()); + playerGear.onInteract(event); + } + + //Handle player gear caching + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onDrop(PlayerDropItemEvent event) + { + GearManager.getInstance().runSyncLater(() -> getGear(event.getPlayer()).updateCache(true), 1); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onPickup(PlayerPickupItemEvent event) + { + GearManager.getInstance().runSyncLater(() -> getGear(event.getPlayer()).updateCache(true), 1); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onClick(InventoryClickEvent event) + { + if (Player.class.isInstance(event.getWhoClicked())) + { + GearManager.getInstance().runSyncLater(() -> getGear((Player)event.getWhoClicked()).updateCache(true), 1); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onJoin(PlayerJoinEvent event) + { + GearManager.getInstance().runSyncLater(() -> + { + if (event.getPlayer().isOnline()) + { + getGear(event.getPlayer()).updateCache(true); + } + }, 5); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onRespawn(PlayerRespawnEvent event) + { + GearManager.getInstance().runSyncLater(() -> getGear(event.getPlayer()).updateCache(true), 1); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onHold(PlayerItemHeldEvent event) + { + GearManager.getInstance().runSyncLater(() -> getGear(event.getPlayer()).updateCache(false), 1); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onInvsee(InvseeModifyOnlineInventoryEvent event) + { + GearManager.getInstance().runSyncLater(() -> getGear(event.getModified()).updateCache(true), 1); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onEquipArmor(PlayerInteractEvent event) + { + if (UtilEvent.isAction(event, ActionType.R)) + { + Player player = event.getPlayer(); + + if (UtilItem.isHelmet(event.getItem()) && player.getInventory().getHelmet() == null) + { + GearManager.getInstance().runSyncLater(() -> getGear(player).updateCache(true), 1); + } + else if (UtilItem.isChestplate(event.getItem()) && player.getInventory().getChestplate() == null) + { + GearManager.getInstance().runSyncLater(() -> getGear(player).updateCache(true), 1); + } + else if (UtilItem.isLeggings(event.getItem()) && player.getInventory().getLeggings() == null) + { + GearManager.getInstance().runSyncLater(() -> getGear(player).updateCache(true), 1); + } + else if (UtilItem.isBoots(event.getItem()) && player.getInventory().getBoots() == null) + { + GearManager.getInstance().runSyncLater(() -> getGear(player).updateCache(true), 1); + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onUseItemFrame(PlayerInteractEntityEvent event) + { + if (event.getRightClicked() instanceof ItemFrame) + { + boolean frameHas = ((ItemFrame)event.getRightClicked()).getItem() != null; + boolean playerHas = event.getPlayer().getItemInHand() != null; + + if (frameHas || playerHas) + { + GearManager.getInstance().runSyncLater(() -> getGear(event.getPlayer()).updateCache(true), 1); + return; + } + } + } + + /** + * @param player - the player whose gear is to be fetched + * @return the {@link PlayerGear} associated with {@code player}. + */ + private PlayerGear getGear(Player player) + { + return GearManager.getInstance().getPlayerGear(player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java new file mode 100644 index 00000000..bcd0f9de --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java @@ -0,0 +1,14 @@ +package mineplex.game.clans.items; + +public enum ItemType +{ + LEGENDARY, + + RARE, + + ARMOR, + + WEAPON, + + BOW; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java new file mode 100644 index 00000000..79757bbf --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java @@ -0,0 +1,201 @@ +package mineplex.game.clans.items; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; + +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +/** + * PlayerGear caches and manages a players set of {@link CustomItem}s that they + * currently wield. + */ +public class PlayerGear +{ + private Player _owner; + + private CustomItem _weapon, _helmet, _chestplate, _leggings, _boots; + private Map _inventory = new HashMap<>(); + private int _lastHeldSlot = 0; + + public PlayerGear(Player owner) + { + _owner = owner; + _lastHeldSlot = owner.getInventory().getHeldItemSlot(); + } + + /** + * Tick & update internal logic for the PlayerGear and required custom items + * that are equipped. + */ + public void update() + { + if (_owner.isOnline()) + { + CustomItem item = getWeapon(); + + if (item != null && item instanceof LegendaryItem) + { + LegendaryItem legendary = (LegendaryItem) item; + legendary.preUpdate(getPlayer()); + legendary.update(getPlayer()); + + if (legendary.OriginalOwner == null) + { + legendary.OriginalOwner = getPlayer().getUniqueId().toString(); + } + } + } + } + + /** + * Refresh the cache of gear due to a potential change + */ + public void updateCache(boolean inventoryChanged) + { + if (inventoryChanged) + { + forEachGear(true, item -> item._lastUser = null); + _inventory.clear(); + for (int i = 0; i < getPlayer().getInventory().getSize(); i++) + { + _inventory.put(i, GearManager.parseItem(getPlayer().getInventory().getItem(i))); + } + } + if (_weapon != null && _weapon instanceof LegendaryItem && _lastHeldSlot != getPlayer().getInventory().getHeldItemSlot()) + { + ((LegendaryItem)_weapon).onUnequip(getPlayer()); + } + _lastHeldSlot = getPlayer().getInventory().getHeldItemSlot(); + _weapon = _inventory.get(_lastHeldSlot); + _helmet = GearManager.parseItem(getPlayer().getInventory().getHelmet()); + _chestplate = GearManager.parseItem(getPlayer().getInventory().getChestplate()); + _leggings = GearManager.parseItem(getPlayer().getInventory().getLeggings()); + _boots = GearManager.parseItem(getPlayer().getInventory().getBoots()); + if (inventoryChanged) + { + forEachGear(true, item -> item._lastUser = getPlayer()); + } + } + + /** + * @return the {@link Player} that owns this gear set. + */ + public Player getPlayer() + { + return _owner; + } + + public String getPlayerName() + { + return getPlayer().getName(); + } + + /** + * Trigger interact events for the set of equipped {@link CustomItem}s in + * gear set. + * + * @param event - the triggering interact event + */ + public void onInteract(PlayerInteractEvent event) + { + forEachGear(false, item -> item.onInteract(event)); + } + + + /** + * Trigger on-attack events for the set of equipped {@link CustomItem}s in + * gear set. + * + * @param event - the triggering on-attack event + */ + public void onAttack(CustomDamageEvent event) + { + forEachGear(false, item -> item.onAttack(event)); + } + + /** + * Trigger attacked events for the set of equipped {@link CustomItem}s in + * gear set. + * + * @param event - the triggering attacked event + */ + public void onAttacked(CustomDamageEvent event) + { + forEachGear(false, item -> item.onAttacked(event)); + } + + private void forEachGear(boolean fullInventory, Consumer itemConsumer) + { + if (fullInventory) + { + _inventory.values().stream().filter(Objects::nonNull).forEach(itemConsumer); + } + else + { + CustomItem weapon = getWeapon(); + if (weapon != null) + { + itemConsumer.accept(weapon); + } + } + CustomItem helmet = getHelmet(); + if (helmet != null) + { + itemConsumer.accept(helmet); + } + CustomItem chestplate = getChestplate(); + if (chestplate != null) + { + itemConsumer.accept(chestplate); + } + CustomItem leggings = getLeggings(); + if (leggings != null) + { + itemConsumer.accept(leggings); + } + CustomItem boots = getBoots(); + if (boots != null) + { + itemConsumer.accept(boots); + } + } + + public CustomItem getWeapon() + { + return _weapon; + } + + public CustomItem getHelmet() + { + return _helmet; + } + + public CustomItem getChestplate() + { + return _chestplate; + } + + public CustomItem getLeggings() + { + return _leggings; + } + + public CustomItem getBoots() + { + return _boots; + } + + /** + * Perform cleanup if necessary. If cleanup was performed, return true. Otherwise return false + */ + public boolean cleanup() + { + return !getPlayer().isOnline(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/RareItemFactory.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/RareItemFactory.java new file mode 100644 index 00000000..598b7fdb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/RareItemFactory.java @@ -0,0 +1,194 @@ +package mineplex.game.clans.items; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.game.clans.items.rares.RareItem; + +/** + * Quick little guide on how to use this thing: + *

+ * The method fabricate() returns an ItemStack. + *

+ * + * For creating a legendary item, do: + *

+ * RareItemFactory.begin(ItemType.LEGENDARY).setLegendary(AlligatorsTooth.class) + * .fabricate(); + *

+ * + * For creating a Flaming Jagged Diamond Sword of Conquering, simply do: + *

+ * RareItemFactory.begin(ItemType.WEAPON).setType(Material.DIAMOND_SWORD). + * setSuperPrefix(FlamingAttribute.class).setPrefix(JaggedAttribute.class). + * setSuffix(ConqueringAttribute.class).fabricate(); + */ +public class RareItemFactory +{ + private Class _superPrefix; + private Class _prefix; + private Class _suffix; + + private ItemType _itemType; + private Material _material; + private CustomItem _item; + + public RareItemFactory(ItemType itemType) + { + _itemType = itemType; + } + + public static RareItemFactory begin(ItemType itemType) + { + return new RareItemFactory(itemType); + } + + public RareItemFactory setType(Material type) + { + _item = new CustomItem(type); + _item.addDullEnchantment(); + _material = type; + return this; + } + + public RareItemFactory setLegendary(Class legendary) + { + if (_itemType.equals(ItemType.LEGENDARY)) + { + try + { + _item = legendary.newInstance(); + _material = _item.getMaterial(); + } + catch (InstantiationException | IllegalAccessException e) + { + e.printStackTrace(); + } + } + else + { + throw new RuntimeException("Unexpected call to setLegendary(LegendaryType)"); + } + + return this; + } + + public RareItemFactory setRare(Class rare) + { + if (_itemType.equals(ItemType.RARE)) + { + try + { + _item = rare.newInstance(); + _material = _item.getMaterial(); + } + catch (InstantiationException | IllegalAccessException e) + { + e.printStackTrace(); + } + } + else + { + throw new RuntimeException("Unexpected call to setRare(RareType)"); + } + + return this; + } + + public RareItemFactory setSuperPrefix(Class superPrefix) + { + _superPrefix = superPrefix; + return this; + } + + public RareItemFactory setSuperPrefix(ItemAttribute superPrefixType) + { + if (superPrefixType != null) + { + setSuperPrefix(superPrefixType.getClass()); + } + return this; + } + + public RareItemFactory setPrefix(Class prefix) + { + _prefix = prefix; + return this; + } + + public RareItemFactory setPrefix(ItemAttribute prefixType) + { + if (prefixType != null) + { + setPrefix(prefixType.getClass()); + } + return this; + } + + public RareItemFactory setSuffix(Class suffix) + { + _suffix = suffix; + return this; + } + + public RareItemFactory setSuffix(ItemAttribute suffixType) + { + if (suffixType != null) + { + setSuffix(suffixType.getClass()); + } + return this; + } + + public ItemStack fabricate() + { + applyAttributes(); + + ItemStack item = _item.toItemStack(); + + return item; + } + + private void applyAttributes() + { + try + { + if (_superPrefix != null) + { + _item.getAttributes().addAttribute(_superPrefix.newInstance()); + } + + if (_prefix != null) + { + _item.getAttributes().addAttribute(_prefix.newInstance()); + } + + if (_suffix != null) + { + _item.getAttributes().addAttribute(_suffix.newInstance()); + } + } + catch (InstantiationException | IllegalAccessException e) + { + e.printStackTrace(); + } + } + + public ItemType getItemType() + { + return _itemType; + } + + public Material getMaterial() + { + return _material; + } + + public CustomItem getWrapper() + { + applyAttributes(); + return _item; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttackAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttackAttribute.java new file mode 100644 index 00000000..0c72d609 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttackAttribute.java @@ -0,0 +1,44 @@ +package mineplex.game.clans.items.attributes; + +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +/** + * Represents an attribute that triggers a special ability after a specified number + * of attacks with a weapon possessing the attribute. + * @author MrTwiggy + * + */ +public abstract class AttackAttribute extends ItemAttribute +{ + + private int _attackLimit; + public int getAttackLimit() { return _attackLimit; } + + private int _attackCount; + + public AttackAttribute(AttributeType type, int attackLimit) + { + super(type); + + _attackLimit = attackLimit; + _attackCount = 0; + } + + @Override + public void onAttack(CustomDamageEvent event) + { + if(event.IsCancelled() || event.isCancelled()) return; + _attackCount++; +// System.out.println("Attack count " + _attackCount + " - " + _attackLimit); + if (_attackCount >= _attackLimit) + { + _attackCount = 0; + triggerAttack(event.GetDamagerEntity(true), event.GetDamageeEntity()); + } + } + + public abstract void triggerAttack(Entity attacker, Entity defender); +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttributeContainer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttributeContainer.java new file mode 100644 index 00000000..5b90f4fa --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttributeContainer.java @@ -0,0 +1,92 @@ +package mineplex.game.clans.items.attributes; + +import java.util.HashSet; +import java.util.Set; + +public class AttributeContainer +{ + + private ItemAttribute _superPrefix; + public ItemAttribute getSuperPrefix() { return _superPrefix; } + public void setSuperPrefix(ItemAttribute attribute) { _superPrefix = attribute; } + + private ItemAttribute _prefix; + public ItemAttribute getPrefix() { return _prefix; } + public void setPrefix(ItemAttribute attribute) { _prefix = attribute; } + + private ItemAttribute _suffix; + public ItemAttribute getSuffix() { return _suffix; } + public void setSuffix(ItemAttribute attribute) { _suffix = attribute; } + + public AttributeContainer(ItemAttribute superPrefix, ItemAttribute prefix, ItemAttribute suffix) + { + _superPrefix = superPrefix; + _prefix = prefix; + _suffix = suffix; + } + + public AttributeContainer() + { + this(null, null, null); + } + + public Set getAttributes() + { + Set attributes = new HashSet(); + + if (_superPrefix != null) attributes.add(_superPrefix); + if (_prefix != null) attributes.add(_prefix); + if (_suffix != null) attributes.add(_suffix); + + return attributes; + } + + public Set getRemainingTypes() + { + Set remainingTypes = new HashSet(); + + if (_superPrefix == null) remainingTypes.add(AttributeType.SUPER_PREFIX); + if (_prefix == null) remainingTypes.add(AttributeType.PREFIX); + if (_suffix == null) remainingTypes.add(AttributeType.SUFFIX); + + return remainingTypes; + } + + public String formatItemName(String displayName) + { + String itemName = displayName; + + if (_prefix != null) + { + itemName = _prefix.getDisplayName() + " " + itemName; + } + + if (_superPrefix != null) + { + itemName = _superPrefix.getDisplayName() + " " + itemName; + } + + if (_suffix != null) + { + itemName += " of " + _suffix.getDisplayName(); + } + + return itemName; + } + + public void addAttribute(ItemAttribute attribute) + { + switch(attribute.getType()) + { + case SUPER_PREFIX: + setSuperPrefix(attribute); + break; + case PREFIX: + setPrefix(attribute); + break; + case SUFFIX: + setSuffix(attribute); + break; + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttributeType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttributeType.java new file mode 100644 index 00000000..df1a5995 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/AttributeType.java @@ -0,0 +1,8 @@ +package mineplex.game.clans.items.attributes; + +public enum AttributeType +{ + SUPER_PREFIX, + PREFIX, + SUFFIX; +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/DamageAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/DamageAttribute.java new file mode 100644 index 00000000..b61ef7dd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/DamageAttribute.java @@ -0,0 +1,31 @@ +package mineplex.game.clans.items.attributes; + +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +public abstract class DamageAttribute extends ItemAttribute +{ + private double _bonusDamage; + public double getBonusDamage() { return _bonusDamage; } + + public DamageAttribute(AttributeType type, ValueDistribution damageGen) + { + super(type); + + _bonusDamage = damageGen.generateValue(); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + if (grantBonusDamage(event.GetDamageeEntity())) + { + event.AddMod("Damage Attribute", _bonusDamage); + } + } + + public abstract boolean grantBonusDamage(Entity defender); +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java new file mode 100644 index 00000000..d4be2207 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java @@ -0,0 +1,151 @@ +package mineplex.game.clans.items.attributes; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +/** + * Represents an attribute that can be attached to {@link CustomItem} to augment their abilities + * and special effects on trigger. + * @author MrTwiggy + * + */ +public abstract class ItemAttribute +{ + + private AttributeType _type; + public AttributeType getType() { return _type; } + public boolean matchesType(AttributeType type) { return _type == type; } + + public ItemAttribute(AttributeType type) + { + _type = type; + } + + /** + * @return the attribute name display to players. + */ + public abstract String getDisplayName(); + + /** + * @return a user-friendly description of this attribute, entailing it's effects + * and current associated values. + */ + public String getDescription() { return "???IMPLEMENT???"; } + + public void onInteract(PlayerInteractEvent event) + { + // Implementation left to subclasses. + } + + public void onAttack(CustomDamageEvent event) + { + // Implementation left to subclasses. + } + + public void onAttacked(CustomDamageEvent event) + { + // Implementation left to subclasses. + } + + /** + * @param minValue - the minimum value for attribute value range + * @param maxValue - the maximum value for attribute value range + * @return newly instantiated {@link ValueDistribution} for attribute values in range [{@code minValue}. {@code maxValue}]. + */ + public static ValueDistribution generateDistribution(double minValue, double maxValue) + { + return new ValueDistribution(minValue, maxValue); + } + + /** + * @param amplifier - the amplifier for a potion effect intensity + * @return the roman-numeral properly representing the amplifier + */ + public static String amplifierToRoman(int amplifier) + { + return integerToRomanNumeral(amplifier + 1); // Add one because amplifiers are zero-based + } + + // Ugly int-to-roman numeral conversion found online. Don't judge! + public static String integerToRomanNumeral(int input) { + if (input < 1 || input > 3999) + return "???"; + String s = ""; + while (input >= 1000) { + s += "M"; + input -= 1000; } + while (input >= 900) { + s += "CM"; + input -= 900; + } + while (input >= 500) { + s += "D"; + input -= 500; + } + while (input >= 400) { + s += "CD"; + input -= 400; + } + while (input >= 100) { + s += "C"; + input -= 100; + } + while (input >= 90) { + s += "XC"; + input -= 90; + } + while (input >= 50) { + s += "L"; + input -= 50; + } + while (input >= 40) { + s += "XL"; + input -= 40; + } + while (input >= 10) { + s += "X"; + input -= 10; + } + while (input >= 9) { + s += "IX"; + input -= 9; + } + while (input >= 5) { + s += "V"; + input -= 5; + } + while (input >= 4) { + s += "IV"; + input -= 4; + } + while (input >= 1) { + s += "I"; + input -= 1; + } + return s; + } + + protected boolean isTeammate(Entity attacker, Entity defender) + { + if (attacker == null || defender == null) return false; + // Don't count attacks towards teammates + if (attacker instanceof Player && defender instanceof Player) + { + ClansUtility.ClanRelation relation = ClansManager.getInstance().getRelation((Player) attacker, (Player) defender); + if (relation == ClansUtility.ClanRelation.ALLY + || relation == ClansUtility.ClanRelation.SAFE + || relation == ClansUtility.ClanRelation.SELF) + { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ConqueringArmorAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ConqueringArmorAttribute.java new file mode 100644 index 00000000..d339abe7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ConqueringArmorAttribute.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.items.attributes.armor; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +// A.K.A Conquering for Armor +public class ConqueringArmorAttribute extends ItemAttribute +{ + private static ValueDistribution reductionGen = generateDistribution(2.5d, 6.25d); + private double _reduction; + + public ConqueringArmorAttribute() + { + super(AttributeType.SUFFIX); + _reduction = reductionGen.generateValue() / 100; + } + + @Override + public String getDisplayName() + { + return "Conquering"; + } + + @Override + public void onAttacked(CustomDamageEvent event) + { + DamageCause cause = event.GetCause(); + Entity attacker = event.GetDamagerEntity(true); + + if (reducesDamage(cause, attacker)) + { + event.AddMult("Conquering Armor", new String(), 1 - _reduction, false); +// System.out.println("Reduced damage by " + reduction); + } + else + { +// System.out.println("Armor doesn't reduce " + cause); + } + } + + @Override + public String getDescription() + { + return String.format("%.1f%% damage taken from mobs & bosses", (1 - _reduction) * 100); + } + + public boolean reducesDamage(DamageCause cause, Entity attacker) + { + return !(attacker instanceof Player); // Reduces damage from all entities + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/EscapeAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/EscapeAttribute.java new file mode 100644 index 00000000..c4f0db81 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/EscapeAttribute.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.items.attributes.armor; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class EscapeAttribute extends ItemAttribute +{ + // TODO: Replace with your generators + private static ValueDistribution healGen = generateDistribution(4, 12); // Value generator for heal amount + + private int _healPercent; + + public EscapeAttribute() + { + super(AttributeType.SUFFIX); + + _healPercent = healGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return ""; // TODO: Fill in name + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/FlatReductionAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/FlatReductionAttribute.java new file mode 100644 index 00000000..b78b4d14 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/FlatReductionAttribute.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.items.attributes.armor; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; + +public abstract class FlatReductionAttribute extends ReductionAttribute +{ + + private double _reduction; + public double getFlatReduction() { return _reduction; } + + public FlatReductionAttribute(AttributeType type, ValueDistribution reductionGen, ReductionConfig config) + { + super(type, config); + + _reduction = reductionGen.generateValue(); + } + + @Override + public double getDamageReduction(double originalDamage) + { + return _reduction; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java new file mode 100644 index 00000000..69313c2a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java @@ -0,0 +1,30 @@ +package mineplex.game.clans.items.attributes.armor; + +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class LavaAttribute extends PercentReductionAttribute +{ + private static ValueDistribution reductionGen = generateDistribution(0.2d, 1.0d); // Value generator for heal amount + private static ReductionConfig lavaConfig = new ReductionConfig(DamageCause.FIRE, DamageCause.LAVA, DamageCause.FIRE_TICK); + + public LavaAttribute() + { + super(AttributeType.SUPER_PREFIX, reductionGen, lavaConfig); + } + + @Override + public String getDisplayName() + { + return "Lava Forged"; + } + + @Override + public String getDescription() + { + return String.format("Reduces damage from fire and lava by %.1f%%", getReductionPercent() * 100d); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java new file mode 100644 index 00000000..99606cb4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java @@ -0,0 +1,30 @@ +package mineplex.game.clans.items.attributes.armor; + +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class PaddedAttribute extends FlatReductionAttribute +{ + private static ValueDistribution reductionGen = generateDistribution(1.0d, 4.0d); + private static ReductionConfig config = new ReductionConfig(DamageCause.FALL); + + public PaddedAttribute() + { + super(AttributeType.PREFIX, reductionGen, config); + } + + @Override + public String getDisplayName() + { + return "Padded"; + } + + @Override + public String getDescription() + { + return String.format("-%.1f damage taken from falls", getFlatReduction()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PercentReductionAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PercentReductionAttribute.java new file mode 100644 index 00000000..68132400 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PercentReductionAttribute.java @@ -0,0 +1,24 @@ +package mineplex.game.clans.items.attributes.armor; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; + +public abstract class PercentReductionAttribute extends ReductionAttribute +{ + private double _reductionPercent; + public double getReductionPercent() { return _reductionPercent; } + + public PercentReductionAttribute(AttributeType type, ValueDistribution reductionGen, ReductionConfig config) + { + super(type, config); + + _reductionPercent = reductionGen.generateValue(); + } + + @Override + public double getDamageReduction(double originalDamage) + { + return originalDamage * _reductionPercent; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java new file mode 100644 index 00000000..764c44d1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.items.attributes.armor; + +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public abstract class ReductionAttribute extends ItemAttribute +{ + + private ReductionConfig _config; + + public ReductionAttribute(AttributeType type, ReductionConfig config) + { + super(type); + + _config = config; + } + + @Override + public void onAttacked(CustomDamageEvent event) + { + DamageCause cause = event.GetCause(); + Entity attacker = event.GetDamagerEntity(true); + + if (reducesDamage(cause, attacker)) + { + double damage = event.GetDamage(); + double reduction = getDamageReduction(damage); + event.AddMod("Reduction Armor", -reduction); +// System.out.println("Reduced damage by " + reduction); + } + else + { +// System.out.println("Armor doesn't reduce " + cause); + } + } + + public boolean reducesDamage(DamageCause cause, Entity attacker) + { + return _config.reducesDamage(cause, attacker); + } + + public abstract double getDamageReduction(double originalDamage); +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionConfig.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionConfig.java new file mode 100644 index 00000000..034f52f2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionConfig.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.items.attributes.armor; + +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +public class ReductionConfig +{ + + private Set _reducedAttackers; // EntityTypes whose attacks are reduced by this attribute + private Set _reducedCauses; // DamageCauses that are reduced by this attribute + + public ReductionConfig() + { + _reducedAttackers = new HashSet(); + _reducedCauses = new HashSet(); + } + + public ReductionConfig(DamageCause... reducedCauses) + { + this(); + + for (DamageCause cause : reducedCauses) + { + _reducedCauses.add(cause); + } + } + + public ReductionConfig(EntityType... reducedAttackers) + { + this(); + + for (EntityType attacker : reducedAttackers) + { + _reducedAttackers.add(attacker); + } + } + + public boolean reducesDamage(DamageCause cause, Entity attacker) + { + return _reducedCauses.contains(cause) || (attacker != null && _reducedAttackers.contains(attacker.getType())); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java new file mode 100644 index 00000000..10ab3c7a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java @@ -0,0 +1,29 @@ + package mineplex.game.clans.items.attributes.armor; + +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class ReinforcedAttribute extends FlatReductionAttribute +{ + private static ValueDistribution reductionGen = generateDistribution(0.5d, 1.0d); + private static ReductionConfig config = new ReductionConfig(DamageCause.ENTITY_ATTACK); + + public ReinforcedAttribute() + { + super(AttributeType.PREFIX, reductionGen, config); + } + + @Override + public String getDisplayName() + { + return "Reinforced"; + } + + @Override + public String getDescription() + { + return String.format("-%.1f damage taken from melee", getFlatReduction()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SeaAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SeaAttribute.java new file mode 100644 index 00000000..4292b3d5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SeaAttribute.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.items.attributes.armor; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class SeaAttribute extends ItemAttribute +{ + // TODO: Replace with your generators + private static ValueDistribution healGen = generateDistribution(4, 12); // Value generator for heal amount + + private int _healPercent; + + public SeaAttribute() + { + super(AttributeType.SUFFIX); + + _healPercent = healGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return ""; // TODO: Fill in name + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java new file mode 100644 index 00000000..23d2767a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java @@ -0,0 +1,30 @@ +package mineplex.game.clans.items.attributes.armor; + +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class SlantedAttribute extends FlatReductionAttribute +{ + private static ValueDistribution reductionGen = generateDistribution(0.5d, 1.5d); + private static ReductionConfig config = new ReductionConfig(DamageCause.PROJECTILE); + + public SlantedAttribute() + { + super(AttributeType.PREFIX, reductionGen, config); + } + + @Override + public String getDisplayName() + { + return "Slanted"; + } + + @Override + public String getDescription() + { + return String.format("-%.1f damage taken from projectiles", getFlatReduction()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/DestructionAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/DestructionAttribute.java new file mode 100644 index 00000000..b9586869 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/DestructionAttribute.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; + +public class DestructionAttribute extends ItemAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution fireGen = generateDistribution(60, 120); + + + public DestructionAttribute() + { + super(AttributeType.SUFFIX); + } + + @Override + public String getDisplayName() + { + return ""; + } + + @Override + public String getDescription() + { + return ""; + } + + @Override + public void onAttack(CustomDamageEvent event) + { + + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/HeavyArrowsAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/HeavyArrowsAttribute.java new file mode 100644 index 00000000..f5e55d42 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/HeavyArrowsAttribute.java @@ -0,0 +1,41 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; + +public class HeavyArrowsAttribute extends ItemAttribute +{ + private static ValueDistribution knockbackGen = generateDistribution(25, 75); + + private double _knockbackPercent; + + public HeavyArrowsAttribute() + { + super(AttributeType.PREFIX); + + _knockbackPercent = knockbackGen.generateValue(); + } + + @Override + public String getDisplayName() + { + return "Heavy"; + } + + @Override + public String getDescription() + { + return String.format("Increase knockback by %.2f%%", _knockbackPercent); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + double knockback = (_knockbackPercent / 100d) * 6; + event.AddKnockback("Heavy Attribute", knockback); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/HuntingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/HuntingAttribute.java new file mode 100644 index 00000000..9e7d680d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/HuntingAttribute.java @@ -0,0 +1,56 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class HuntingAttribute extends ItemAttribute +{ + private static ValueDistribution amountGen = generateDistribution(0, 2); // Value generator for slow amount range + private static ValueDistribution durationGen = generateDistribution(1, 4); // Value generator for slow duration range + + private int _slowAmount; // The slowness level/amplifier + private double _slowDuration; // The duration (in ticks) of slow effect + + public HuntingAttribute() + { + super(AttributeType.PREFIX); + + _slowAmount = amountGen.generateIntValue(); + _slowDuration = durationGen.generateValue(); + } + + @Override + public String getDisplayName() + { + return "Hunting"; + } + + @Override + public String getDescription() + { + return String.format("Damaged enemies receive slowness %s for %.2f seconds", amplifierToRoman(_slowAmount), _slowDuration); + } + + @Override + public void onAttacked(CustomDamageEvent event) + { + Player damager = event.GetDamagerPlayer(true); + + if (damager != null) + { + damager.addPotionEffect(generateSlowEffect()); // Slow attacking player + } + } + + private PotionEffect generateSlowEffect() + { + return new PotionEffect(PotionEffectType.SLOW, (int) (_slowDuration * 20), _slowAmount); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/InverseAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/InverseAttribute.java new file mode 100644 index 00000000..c37d120c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/InverseAttribute.java @@ -0,0 +1,39 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class InverseAttribute extends ItemAttribute +{ +private static ValueDistribution knockbackGen = generateDistribution(0.d, 1.d); + + private double _knockbackModifier; + + public InverseAttribute() + { + super(AttributeType.PREFIX); + + _knockbackModifier = knockbackGen.generateValue(); + } + + @Override + public String getDisplayName() + { + return "Inverse"; + } + + @Override + public String getDescription() + { + return String.format("Reverse knockback and modify amount to %.2f percent", (.5d + _knockbackModifier) * 100d); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + event.AddKnockback("InverseAttribute", _knockbackModifier); + event.invertKnockback(); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/LeechingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/LeechingAttribute.java new file mode 100644 index 00000000..bfc0daf8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/LeechingAttribute.java @@ -0,0 +1,51 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.core.common.util.UtilMath; +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +public class LeechingAttribute extends ItemAttribute +{ + private static ValueDistribution healGen = generateDistribution(5, 15); + + private int _healPercent; + + public LeechingAttribute() + { + super(AttributeType.SUPER_PREFIX); + + _healPercent = healGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return "Leeching"; + } + + @Override + public String getDescription() + { + return String.format("Heal for %d percentage of damage dealt", _healPercent); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + Player damager = event.GetDamagerPlayer(true); + + double damage = event.GetDamage(); + double healAmount = damage * (_healPercent / 100d); + heal(damager, healAmount); + } + + private void heal(Player player, double healAmount) + { + player.setHealth(UtilMath.clamp(player.getHealth() + healAmount, 0, 20)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/ReboundingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/ReboundingAttribute.java new file mode 100644 index 00000000..51889a39 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/ReboundingAttribute.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; + +public class ReboundingAttribute extends ItemAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution fireGen = generateDistribution(60, 120); + + + public ReboundingAttribute() + { + super(AttributeType.SUPER_PREFIX); + } + + @Override + public String getDisplayName() + { + return ""; + } + + @Override + public String getDescription() + { + return ""; + } + + @Override + public void onAttack(CustomDamageEvent event) + { + + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/RecursiveAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/RecursiveAttribute.java new file mode 100644 index 00000000..a18a0add --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/RecursiveAttribute.java @@ -0,0 +1,37 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.DamageAttribute; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; + +public class RecursiveAttribute extends DamageAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 6); + + public RecursiveAttribute() + { + super(AttributeType.PREFIX, attackGen); + } + + @Override + public String getDisplayName() + { + return "Recursive"; + } + + @Override + public String getDescription() + { + return String.format("Increase damage by %.2f half-hearts", getBonusDamage()); + } + + @Override + public boolean grantBonusDamage(Entity defender) + { + return true; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/ScorchingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/ScorchingAttribute.java new file mode 100644 index 00000000..c8bcfb63 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/ScorchingAttribute.java @@ -0,0 +1,43 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttackAttribute; +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; + +import org.bukkit.entity.Entity; + +public class ScorchingAttribute extends AttackAttribute +{ + private static ValueDistribution fireGen = generateDistribution(2, 6); + + private double _fireDuration; + + public ScorchingAttribute() + { + super(AttributeType.SUPER_PREFIX, 1); // Activates every hit + _fireDuration = fireGen.generateValue(); + } + + @Override + public String getDisplayName() + { + return "Scorching"; + } + + @Override + public String getDescription() + { + return String.format("Struck enemies catch fire for %.2f seconds", _fireDuration); + } + + @Override + public void triggerAttack(Entity attacker, Entity defender) + { + if (isTeammate(attacker, defender)) + { + return; + } + defender.setFireTicks((int) (_fireDuration * 20)); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/SlayingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/SlayingAttribute.java new file mode 100644 index 00000000..e9301156 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/SlayingAttribute.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.DamageAttribute; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Monster; + +public class SlayingAttribute extends DamageAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 12); + + public SlayingAttribute() + { + super(AttributeType.SUFFIX, attackGen); + } + + @Override + public String getDisplayName() + { + return "Slaying"; + } + + @Override + public String getDescription() + { + return String.format("Increase damage by %.2f half-hearts against mobs & bosses", getBonusDamage()); + } + + @Override + public boolean grantBonusDamage(Entity defender) + { + return defender instanceof Monster; // TODO: Check to see if defender is also a WorldEvent boss? + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/SpectralAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/SpectralAttribute.java new file mode 100644 index 00000000..3107b561 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/bow/SpectralAttribute.java @@ -0,0 +1,38 @@ +package mineplex.game.clans.items.attributes.bow; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Entity; + +public class SpectralAttribute extends ItemAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution fireGen = generateDistribution(60, 120); + + + public SpectralAttribute() + { + super(AttributeType.SUPER_PREFIX); + } + + @Override + public String getDisplayName() + { + return ""; + } + + @Override + public String getDescription() + { + return ""; + } + + @Override + public void onAttack(CustomDamageEvent event) + { + + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java new file mode 100644 index 00000000..02c7744b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java @@ -0,0 +1,37 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.DamageAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class ConqueringAttribute extends DamageAttribute +{ + private static ValueDistribution damageGen = generateDistribution(1.0d, 4.0d); + + public ConqueringAttribute() + { + super(AttributeType.SUFFIX, damageGen); + } + + @Override + public String getDisplayName() + { + return "Conquering"; + } + + @Override + public String getDescription() + { + return String.format("%.2f bonus damage against mobs & bosses", getBonusDamage()); + } + + @Override + public boolean grantBonusDamage(Entity entity) + { + return !(entity instanceof Player); // TODO: Check to see if entity is mob and/or a boss! + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java new file mode 100644 index 00000000..d6a25bb2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java @@ -0,0 +1,48 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.page.ClanMainPage; +import mineplex.game.clans.items.attributes.AttackAttribute; +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; + +import org.bukkit.GameMode; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class FlamingAttribute extends AttackAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution fireGen = generateDistribution(60, 120); + + private int _fireDuration; + + public FlamingAttribute() + { + super(AttributeType.SUPER_PREFIX, attackGen.generateIntValue()); + _fireDuration = fireGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return "Flaming"; + } + + @Override + public String getDescription() + { + return String.format("Every %d attacks gives Fire for %.1f seconds", getAttackLimit(), (_fireDuration / 20d)); + } + + @Override + public void triggerAttack(Entity attacker, Entity defender) + { + if(attacker instanceof Player && ClansManager.getInstance().isSafe((Player) attacker)) return; + if(defender instanceof Player && ClansManager.getInstance().isSafe((Player) defender)) return; + if(attacker instanceof Player && ((Player)attacker).getGameMode().equals(GameMode.CREATIVE)) return; + if (isTeammate(attacker, defender)) return; + defender.setFireTicks(_fireDuration); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java new file mode 100644 index 00000000..0e8b8a8a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +/** + * Frosted attribute to be added onto custom armor. Applies a slowing effect to players that + * attack the wearer of a Frosted {@link CustomItem}. + * @author MrTwiggy + * + */ +public class FrostedAttribute extends ItemAttribute +{ + private static ValueDistribution amountGen = generateDistribution(0, 3); // Value generator for slow amount range + private static ValueDistribution durationGen = generateDistribution(20, 60); // Value generator for slow duration range + + private int _slowAmount; // The slowness level/amplifier + private int _slowDuration; // The duration (in ticks) of slow effect + + /** + * Class constructor + */ + public FrostedAttribute() + { + super(AttributeType.SUPER_PREFIX); + + _slowAmount = amountGen.generateIntValue(); + _slowDuration = durationGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return "Frosted"; + } + + @Override + public String getDescription() + { + return String.format("Apply slowness %s for %d ticks to enemies", amplifierToRoman(_slowAmount), _slowDuration); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + Player victim = event.GetDamageePlayer(); + + if (victim != null) + { + if (isTeammate(event.GetDamagerPlayer(true), victim)) return; + victim.addPotionEffect(generateSlowEffect()); // Slow attacking player + } + } + + private PotionEffect generateSlowEffect() + { + return new PotionEffect(PotionEffectType.SLOW, _slowDuration, _slowAmount); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java new file mode 100644 index 00000000..0abc5d25 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java @@ -0,0 +1,53 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttackAttribute; +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +public class HasteAttribute extends AttackAttribute +{ + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution speedGen = generateDistribution(0, 2); + private static ValueDistribution durationGen = generateDistribution(60, 120); + + private int _speedAmount; + private int _speedDuration; + + public HasteAttribute() + { + super(AttributeType.SUFFIX, attackGen.generateIntValue()); + + _speedAmount = speedGen.generateIntValue(); + _speedDuration = durationGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return "Haste"; + } + + @Override + public String getDescription() + { + return String.format("Every %d attacks gives you Speed %s for %.1f seconds", getAttackLimit(), amplifierToRoman(_speedAmount), (_speedDuration / 20f)); + } + + @Override + public void triggerAttack(Entity attacker, Entity defender) + { + if (isTeammate(attacker, defender)) return; + if (attacker instanceof Player) + { + Player player = (Player) attacker; + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, _speedDuration, _speedAmount)); + } + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HeavyAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HeavyAttribute.java new file mode 100644 index 00000000..b1be4ca9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HeavyAttribute.java @@ -0,0 +1,39 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class HeavyAttribute extends ItemAttribute +{ + private static ValueDistribution knockbackGen = generateDistribution(25, 75); // Value generator for knockback % boost. + + private double _knockbackBoost; + + public HeavyAttribute() + { + super(AttributeType.PREFIX); + + _knockbackBoost = knockbackGen.generateValue(); + } + + @Override + public String getDisplayName() + { + return "Heavy"; + } + + @Override + public String getDescription() + { + return String.format("%.1f%% additional knockback", _knockbackBoost); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + double knockback = (_knockbackBoost / 100d) * event.getKnockbackValue(); + event.AddKnockback("Heavy Attribute", knockback); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java new file mode 100644 index 00000000..0bdce1eb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java @@ -0,0 +1,37 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttackAttribute; +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.generation.ValueDistribution; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +public class JaggedAttribute extends AttackAttribute { + private static ValueDistribution attackGen = generateDistribution(2, 4); + + public JaggedAttribute() { + super(AttributeType.PREFIX, attackGen.generateIntValue()); + } + + @Override + public String getDisplayName() { + return "Jagged"; + } + + @Override + public String getDescription() { + return String.format("Every %d attacks mini-stuns enemies", getAttackLimit()); + } + + @Override + public void triggerAttack(Entity attacker, Entity defender) { + if (isTeammate(attacker, defender)) return; + defender.setVelocity(new Vector(0, 0, 0)); + if (defender instanceof LivingEntity) + ((LivingEntity) defender).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20, 1, false, false)); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java new file mode 100644 index 00000000..c1c996ab --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java @@ -0,0 +1,36 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.DamageAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +import org.bukkit.entity.Entity; + +public class SharpAttribute extends DamageAttribute +{ + private static ValueDistribution damageGen = generateDistribution(0.5d, 1.5d); + + public SharpAttribute() + { + super(AttributeType.PREFIX, damageGen); + } + + @Override + public String getDisplayName() + { + return "Sharp"; + } + + @Override + public String getDescription() + { + return String.format("%.2f bonus damage", getBonusDamage()); + } + + @Override + public boolean grantBonusDamage(Entity defender) + { + return true; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SmashingAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SmashingAttribute.java new file mode 100644 index 00000000..6dc1833b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SmashingAttribute.java @@ -0,0 +1,26 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class SmashingAttribute extends ItemAttribute +{ + // TODO: Replace with your generators + private static ValueDistribution healGen = generateDistribution(4, 12); // Value generator for heal amount + + private int _healPercent; + + public SmashingAttribute() + { + super(AttributeType.SUFFIX); + _healPercent = healGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return ""; // TODO: Fill in name + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SwiftAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SwiftAttribute.java new file mode 100644 index 00000000..587fb09b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SwiftAttribute.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; + +public class SwiftAttribute extends ItemAttribute +{ + // TODO: Replace with your generators + private static ValueDistribution healGen = generateDistribution(4, 12); // Value generator for heal amount + + private int _healPercent; + + public SwiftAttribute() + { + super(AttributeType.PREFIX); + + _healPercent = healGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return ""; // TODO: Fill in name + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java new file mode 100644 index 00000000..ea4279da --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java @@ -0,0 +1,52 @@ +package mineplex.game.clans.items.attributes.weapon; + +import mineplex.game.clans.items.attributes.AttributeType; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +public class VampiricAttribute extends ItemAttribute +{ + private static ValueDistribution healGen = generateDistribution(4, 12); + + private int _healPercent; + + public VampiricAttribute() + { + super(AttributeType.SUPER_PREFIX); + + _healPercent = healGen.generateIntValue(); + } + + @Override + public String getDisplayName() + { + return "Vampiric"; + } + + @Override + public String getDescription() + { + return String.format("Heal yourself for %d% of damage dealt", _healPercent); + } + + @Override + public void onAttack(CustomDamageEvent event) + { + Player damager = event.GetDamagerPlayer(false); + + if (isTeammate(damager, event.GetDamageePlayer())) return; + + double damage = event.GetDamage(); + double healAmount = damage * (_healPercent / 100d); + heal(damager, healAmount); + } + + private void heal(Player player, double healAmount) + { + player.setHealth(player.getHealth() + healAmount); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java new file mode 100644 index 00000000..fd08528e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.items.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.items.GearManager; + +public class GearCommand extends CommandBase +{ + public GearCommand(GearManager plugin) + { + super(plugin, GearManager.Perm.GEAR_COMMAND, "gear", "custom-gear"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length == 0) + { + Plugin.openShop(caller); + } + else + { + caller.updateInventory(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/RuneCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/RuneCommand.java new file mode 100644 index 00000000..e5fc4854 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/RuneCommand.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.items.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.runes.RuneManager; +import mineplex.game.clans.items.runes.RuneManager.RuneAttribute; + +/** + * Command to give yourself a rune + */ +public class RuneCommand extends CommandBase +{ + private RuneManager _rune; + + public RuneCommand(GearManager plugin) + { + super(plugin, GearManager.Perm.RUNE_COMMAND, "rune", "giverune", "getrune"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (_rune == null) + { + _rune = Plugin.getRuneManager(); + } + + if (args.length < 1) + { + UtilPlayer.message(caller, F.main("Rune", "Usage: /" + _aliasUsed + " ")); + UtilPlayer.message(caller, F.main(Plugin.getName(), "Available types:")); + for (RuneAttribute rune : RuneAttribute.values()) + { + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + rune.toString()); + } + return; + } + RuneAttribute rune = RuneAttribute.getFromString(args[0]); + if (rune == null) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Invalid rune type! Available types:")); + for (RuneAttribute type : RuneAttribute.values()) + { + UtilPlayer.message(caller, C.cBlue + "- " + C.cGray + type.toString()); + } + return; + } + UtilInv.insert(caller, _rune.getRune(rune)); + UtilPlayer.message(caller, F.main("Rune", "You have been given a(n) " + F.elem(rune.getDisplay()) + " rune!")); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/economy/GoldToken.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/economy/GoldToken.java new file mode 100644 index 00000000..428d71f6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/economy/GoldToken.java @@ -0,0 +1,36 @@ +package mineplex.game.clans.items.economy; + +import org.bukkit.Material; + +import mineplex.game.clans.items.CustomItem;; + +public class GoldToken extends CustomItem +{ + private int _goldValue; + + public GoldToken() + { + this(0); + } + + public GoldToken(int goldValue) + { + super("Gold Token", null, Material.RABBIT_FOOT); + + _goldValue = goldValue; + } + + public int getGoldValue() + { + return _goldValue; + } + + @Override + public String[] getDescription() + { + return new String[] + { + String.format("A gold token worth %s gold coins.", _goldValue), + }; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/ValueDistribution.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/ValueDistribution.java new file mode 100644 index 00000000..15d13691 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/ValueDistribution.java @@ -0,0 +1,56 @@ +package mineplex.game.clans.items.generation; + +import java.util.Random; + +/** + * Handles the random generation of attribute values in specified value range + * and probability distribution. + * @author MrTwiggy + * + */ +public class ValueDistribution +{ + private static Random random = new Random(); // Used for RNG of value generation + + private double _min; // Minimum value range available for distribution + private double _max; // Maximum value range available for distribution + private double _lambdaScaler; // Scales exponential probability distribution to skew range values + + /** + * Class constructor for distribution of range [min, max] + * @param min - the minimum value for generation range + * @param max - the maximum value for generation range + */ + public ValueDistribution(double min, double max) + { + _min = min; + _max = max; + } + + /** + * @return randomly generated value conforming to the range and value distribution. + */ + public double generateValue() + { + double roll = random.nextDouble() * random.nextDouble(); + + double delta = getRange() * roll; + return _min + delta; + } + + /** + * @return randomly generated distribution value, rounding to nearest integer. + */ + public int generateIntValue() + { + return (int) Math.round(generateValue()); + } + + /** + * @return the value range associated with this distribution. + */ + public double getRange() + { + return _max - _min; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java new file mode 100644 index 00000000..52feeba3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java @@ -0,0 +1,88 @@ +package mineplex.game.clans.items.legendaries; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class AlligatorsTooth extends LegendaryItem +{ + private static final ValueDistribution BOOST_GEN = generateDistribution(0.8d, 1.4d); + private static final double LAND_DAMAGE_BONUS = 7; + private static final double WATER_DAMAGE_BONUS = 11; + + private double _swimSpeed; + private int _soundUpdateCounter; + + public AlligatorsTooth() + { + super("Alligators Tooth", new String[] + { + C.cWhite + "This deadly tooth was stolen from", + C.cWhite + "a nest of reptilian beasts long", + C.cWhite + "ago. Legends say that the holder", + C.cWhite + "is granted the underwater agility", + C.cWhite + "of an Alligator.", + " ", + C.cWhite + "Deals " + C.cYellow + "8 Damage" + C.cWhite + " with attack on land", + C.cWhite + "Deals " + C.cYellow + "12 Damage" + C.cWhite + " with attack in water", + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Gator Stroke", + }, Material.RECORD_4); + + _swimSpeed = BOOST_GEN.generateValue(); + } + + @Override + public void update(Player wielder) + { + if (isInWater(wielder)) + { + // Player gain water breathing while under water with legendary equipped + grantPotionEffect(wielder, PotionEffectType.WATER_BREATHING, 0, 50); + + if (isHoldingRightClick()) + { + propelPlayer(wielder); + if (++_soundUpdateCounter % 3 == 0) + { + wielder.playSound(wielder.getLocation(), Sound.SPLASH2, .5f, 1.25f); + wielder.getLocation().getWorld().playEffect(wielder.getLocation(), Effect.STEP_SOUND, Material.LAPIS_BLOCK.getId()); + } + } + } + } + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + if (isInWater(wielder)) + { + event.AddMod("Alligators Tooth Water Bonus", WATER_DAMAGE_BONUS); + event.AddKnockback("Alligators Tooth Water Bonus", 0.5d); + } + else + { + event.AddMod("Alligators Tooth Land Bonus", LAND_DAMAGE_BONUS); + } + + } + + private void propelPlayer(Player player) + { + Vector direction = player.getLocation().getDirection().normalize(); + direction.multiply(_swimSpeed); + player.setVelocity(direction); + } + + private boolean isInWater(Player player) + { + Material type = player.getLocation().getBlock().getType(); + return type == Material.WATER || type == Material.STATIONARY_WATER; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/DemonicScythe.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/DemonicScythe.java new file mode 100644 index 00000000..48a3d5bb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/DemonicScythe.java @@ -0,0 +1,239 @@ +package mineplex.game.clans.items.legendaries; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.WitherSkull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class DemonicScythe extends LegendaryItem +{ + private long _interactWait; + + static + { + UtilServer.RegisterEvents(new Listener() + { + @EventHandler(priority = EventPriority.LOWEST) + public void onDamagedByFireball(CustomDamageEvent event) + { + Projectile proj = event.GetProjectile(); + if (proj != null && UtilEnt.hasFlag(proj, "DemonicScythe.Projectile")) + { + event.SetCancelled("Unnecessary Scythe Damage"); + return; + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onHit(ProjectileHitEvent event) + { + if (event.getEntity() instanceof WitherSkull) + { + WitherSkull skull = (WitherSkull) event.getEntity(); + + if (!UtilEnt.hasFlag(skull, "DemonicScythe.Projectile")) + { + return; + } + Location hit = skull.getLocation(); + boolean inverted = skull.isCharged(); + skull.remove(); + if (skull.getShooter() == null) + { + return; + } + Player shooter = (Player) skull.getShooter(); + + for (Entity e : skull.getNearbyEntities(3, 3, 3)) + { + if (e instanceof LivingEntity) + { + LivingEntity entity = (LivingEntity) e; + if (UtilEnt.hasFlag(entity, "LegendaryAbility.IgnoreMe")) + { + continue; + } + if (ClansManager.getInstance().getClanUtility().isSafe(entity.getLocation())) + { + continue; + } + if (e instanceof Player) + { + Player target = (Player) e; + if (ClansManager.getInstance().hasTimer(target)) + { + continue; + } + if (ClansManager.getInstance().isInClan(shooter) && ClansManager.getInstance().getClan(shooter).isMember(target)) + { + continue; + } + if (target.getGameMode() == GameMode.CREATIVE || target.getGameMode() == GameMode.SPECTATOR) + { + continue; + } + if (ClansManager.getInstance().getIncognitoManager().Get(target).Hidden) + { + continue; + } + if (ClansManager.getInstance().isInClan(shooter) && ClansManager.getInstance().getClan(shooter).isAlly(ClansManager.getInstance().getClan(target))) + { + continue; + } + if (target.getEntityId() == shooter.getEntityId()) + { + continue; + } + } + + //Damage Event + ClansManager.getInstance().getDamageManager().NewDamageEvent(entity, shooter, null, + DamageCause.CUSTOM, 8, false, true, false, + shooter.getName(), "Wither Skull"); + + //Velocity + Vector trajectory; + if (inverted) + { + trajectory = UtilAlg.getTrajectory2d(entity.getLocation().toVector(), hit.toVector()); + } + else + { + trajectory = UtilAlg.getTrajectory2d(hit.toVector(), entity.getLocation().toVector()); + } + UtilAction.velocity(entity, + trajectory, + 2.6, true, 0, 0.2, 1.4, true); + + //Condition + ClansManager.getInstance().getCondition().Factory().Falling("Wither Skull", entity, shooter, 10, false, true); + } + } + } + } + }); + } + + public DemonicScythe() + { + super("Scythe of the Fallen Lord", new String[] + { + C.cWhite + "An old blade fashioned of nothing more", + C.cWhite + "stray bones, brave adventurers have", + C.cWhite + "imbued it with the remnant powers of a", + C.cWhite + "dark and powerful foe.", + " ", + C.cWhite + "Deals " + C.cYellow + "8 Damage" + C.cWhite + " with attack", + C.cYellow + "Attack" + C.cWhite + " to use " + C.cGreen + "Leach Health", + C.cYellow + "Right Click" + C.cWhite + " to use " + C.cGreen + "Skull Launcher", + C.cYellow + "Shift-Right Click" + C.cWhite + " to use " + C.cGreen + "Gravity Skull Launcher", + }, Material.RECORD_8); + } + + private boolean isTeammate(Entity attacker, Entity defender) + { + if (attacker == null || defender == null) return false; + // Don't count attacks towards teammates + if (attacker instanceof Player && defender instanceof Player) + { + ClansUtility.ClanRelation relation = ClansManager.getInstance().getRelation((Player) attacker, (Player) defender); + if (relation == ClansUtility.ClanRelation.ALLY + || relation == ClansUtility.ClanRelation.SAFE + || relation == ClansUtility.ClanRelation.SELF) + { + return true; + } + } + return false; + } + + @Override + public void update(Player wielder) + { + if (timeSinceLastBlock() >= 98 || (System.currentTimeMillis() - _interactWait) < 98) + { + return; + } + if (ClansManager.getInstance().hasTimer(wielder)) + { + UtilPlayer.message(wielder, F.main("Clans", "You are not allowed to fire skulls whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + if (ClansManager.getInstance().getClanUtility().getClaim(wielder.getLocation()) != null && ClansManager.getInstance().getClanUtility().getClaim(wielder.getLocation()).isSafe(wielder.getLocation())) + { + UtilPlayer.message(wielder, F.main("Clans", "You are not allowed to fire skulls whilst in a safe zone.")); + return; + } + if (!Recharge.Instance.use(wielder, "Scythe Skull Launcher", 9000, true, false)) + { + return; + } + WitherSkull skull = wielder.launchProjectile(WitherSkull.class); + UtilEnt.addFlag(skull, "DemonicScythe.Projectile"); + if (wielder.isSneaking()) + { + skull.setCharged(true); + } + skull.setBounce(false); + skull.setIsIncendiary(false); + skull.setYield(0); + _interactWait = System.currentTimeMillis(); + } + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + if (event.isCancelled()) + { + return; + } + if (ClansManager.getInstance().isSafe(wielder)) + { + return; + } + if (event.GetDamageeEntity() instanceof Player && ClansManager.getInstance().isSafe(event.GetDamageePlayer())) + { + return; + } + if (wielder.getGameMode().equals(GameMode.CREATIVE)) + { + return; + } + if (isTeammate(wielder, event.GetDamageeEntity())) + { + return; + } + if (wielder.getHealth() <= 0) + { + return; + } + event.AddMod("Scythe of the Fallen Lord", 7); + if (!(event.GetDamageeEntity() instanceof Horse) && Recharge.Instance.use(wielder, "Demonic Scythe Heal", 500, false, false)) + { + wielder.setHealth(Math.min(wielder.getMaxHealth(), wielder.getHealth() + 3)); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java new file mode 100644 index 00000000..3747f8bd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/EnergyCrossbow.java @@ -0,0 +1,188 @@ +package mineplex.game.clans.items.legendaries; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.RGBData; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilColor; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTrig; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; + +/* + @deprecated Code probably doesn't work and needs a rewrite + */ +@Deprecated +public class EnergyCrossbow extends LegendaryItem +{ + private static final List PRE_CALCULATED_SPHERE = Collections.unmodifiableList( + UtilTrig.GetSpherePoints(new Vector(0, 0, 0), 1.8d, 1.8d, true, .4d) + ); + + private long _interactWait; + + public EnergyCrossbow() + { + super("Energy Crossbow", UtilText.splitLinesToArray(new String[] + { + C.cWhite + "Legend says ", + " ", + "#" + C.cYellow + "Right-Click" + C.cWhite + " to fire Crossbow." + }, LineFormat.LORE), Material.RECORD_6); + } + + @Override + public void update(Player wielder) + { + if (timeSinceLastBlock() < 98 && (System.currentTimeMillis() - _interactWait) >= 98) + { + if (Recharge.Instance.use(wielder, "Crossbow", 6500, true, true)) + { + fire(wielder); + + _interactWait = System.currentTimeMillis(); + } + } + } + + private void fire(final Player player) + { + UtilServer.RegisterEvents(new Listener() + { + private Location _lastLoc; + + private Arrow _arrow; + private Player _player; + + private RGBData[] colors = { UtilColor.RgbLightRed, UtilColor.RgbLightRed.Lighten(), UtilColor.RgbLightRed.Darken() }; + + { + // Pretty sure this won't work + _player = player; + + Arrow arrow = _player.shootArrow(); + + arrow.setVelocity(arrow.getVelocity().multiply(3.4444444444444)); + + arrow.setShooter(_player); + + _arrow = arrow; + + _player.playSound(_arrow.getLocation(), Sound.BAT_TAKEOFF, 0.1f, 2.f); + _player.playSound(_arrow.getLocation(), Sound.ZOMBIE_WOODBREAK, 0.5f, .5f); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (_arrow == null || _arrow.isDead()) + { + HandlerList.unregisterAll(this); + + return; + } + + if (_lastLoc != null) + { + Location lastLoc = _lastLoc.clone(); + + while (UtilMath.offset(lastLoc, _arrow.getLocation()) > 0.1) + { + lastLoc.add(UtilAlg.getTrajectory(lastLoc, _arrow.getLocation()).multiply(0.1)); + + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, lastLoc, UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.MAX); + } + } + + _lastLoc = _arrow.getLocation(); + } + + private void hit() + { + HandlerList.unregisterAll(this); + + for (Vector vector : PRE_CALCULATED_SPHERE) + { + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, _arrow.getLocation().add(vector), UtilColor.RgbLightRed.ToVector(), 1.0f, 0, ViewDist.MAX); + } + + HashMap targets = UtilEnt.getInRadius(_arrow.getLocation(), 3.d); + for (LivingEntity entity : targets.keySet()) + { + if (entity.equals(_arrow.getShooter())) + continue; + + ClansManager.getInstance().getDamageManager().NewDamageEvent(entity, _player, _arrow, + DamageCause.CUSTOM, 8, true, true, false, + _player.getName(), "Energy Crossbow"); + } + + _arrow.remove(); + _arrow = null; + } + + @EventHandler + public void projectileHit(ProjectileHitEvent event) + { + if (!event.getEntity().equals(_arrow)) + { + return; + } + + ClansManager.getInstance().runSyncLater(this::hit, 1); + } + + @EventHandler + public void entityHurt(EntityDamageByEntityEvent event) + { + if (!event.getDamager().equals(_arrow)) + { + return; + } + + if (event.getEntity().equals(_arrow.getShooter()) || !(event.getEntity() instanceof LivingEntity)) + { + _arrow.remove(); + _arrow = null; + + return; + } + + event.setCancelled(true); + + ClansManager.getInstance().getDamageManager().NewDamageEvent((LivingEntity) event.getEntity(), _player, _arrow, + DamageCause.CUSTOM, 1.5d, true, true, false, + _player.getName(), "Energy Crossbow"); + + hit(); + } + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java new file mode 100644 index 00000000..016aa93c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java @@ -0,0 +1,70 @@ +package mineplex.game.clans.items.legendaries; + +import mineplex.core.recharge.Recharge; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class GiantsBroadsword extends LegendaryItem +{ + private static final int SLOW_AMPLIFIER = 43; + private static final int REGEN_AMPLIFIER = 1; + + public GiantsBroadsword() + { + super("Giants Broadsword", new String[] + { + C.cWhite + "Forged in the godly mines of Plagieus,", + C.cWhite + "this sword has endured thousands of", + C.cWhite + "wars. It is sure to grant glorious", + C.cWhite + "victory in battle.", + C.cWhite + " ", + C.cWhite + "Deals " + C.cYellow + "10 Damage" + C.cWhite + " with attack", + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Shield", + }, Material.GOLD_RECORD); + } + + @Override + public void update(Player wielder) + { + if (isHoldingRightClick()) + { + buffPlayer(wielder); + + UtilParticle.PlayParticle(ParticleType.HEART, wielder.getEyeLocation().add(0, 0.25, 0), -.5f + (float) Math.random(), -.5f + (float) Math.random(), -.5f + (float) Math.random(), .2f, 1, ViewDist.NORMAL); + wielder.playSound(wielder.getLocation(), Sound.LAVA_POP, 1f, 2f); + return; + } + + UtilParticle.PlayParticle(ParticleType.MAGIC_CRIT, wielder.getLocation().add(0, 1, 0), 0, 0, 0, .2f, 3, ViewDist.NORMAL); + } + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + if (isHoldingRightClick()) + { + event.SetCancelled("Giants Broadsword effects"); + return; + } + + event.AddMod("Giants Bonus", 9); + event.AddKnockback("Giants Sword", 0.5d); + } + + private void buffPlayer(Player player) + { + grantPotionEffect(player, PotionEffectType.SLOW, 40, SLOW_AMPLIFIER); + if (Recharge.Instance.use(player, "Giants Broadsword Regen", 250L, false, false, false)) + { + grantPotionEffect(player, PotionEffectType.REGENERATION, 5, REGEN_AMPLIFIER); //Regen + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java new file mode 100644 index 00000000..36459fac --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperAxe.java @@ -0,0 +1,82 @@ +package mineplex.game.clans.items.legendaries; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.C; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class HyperAxe extends LegendaryItem +{ + private static final long ATTACK_RATE_DURATION = 1000 / 10; + private static final ValueDistribution AMOUNT_GEN = generateDistribution(0, 3); // [1, 4] speed amount + private static final ValueDistribution DURATION_GEN = generateDistribution(80, 320); // [4, 16] seconds speed duration + + private final int _speedAmount; + private final int _speedDuration; + + private long _lastAttack; + + public HyperAxe() + { + super("Hyper Axe", new String[] + { + C.cWhite + "Of all the weapons known to man,", + C.cWhite + "none matches the savagery of the", + C.cWhite + "Hyper Axe. Infused with a rabbit's", + C.cWhite + "speed and a pigman's ferocity, this", + C.cWhite + "blade can rip through any opponent.", + C.cWhite + " ", + C.cWhite + "Hit delay is reduced by " + C.cYellow + "50%", + C.cWhite + "Deals " + C.cYellow + "6 Damage" + C.cWhite + " with attack", + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Dash", + }, Material.RECORD_3); + _speedAmount = AMOUNT_GEN.generateIntValue(); + _speedDuration = DURATION_GEN.generateIntValue(); + _lastAttack = 0; + } + + @Override + public void update(Player wielder) + { + if (isHoldingRightClick()) + { + buffPlayer(wielder); + } + } + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + if (timeSinceLastAttack() >= ATTACK_RATE_DURATION) + { + event.SetIgnoreRate(true); + + event.AddMod("Hyper Axe", 5); + _lastAttack = System.currentTimeMillis(); + } + else + { + event.SetCancelled("Hyper Axe Cooldown"); + } + } + + private long timeSinceLastAttack() + { + return System.currentTimeMillis() - _lastAttack; + } + + private void buffPlayer(Player wielder) + { + if (Recharge.Instance.usable(wielder, "Hyper Rush", true)) + { + Recharge.Instance.use(wielder, "Hyper Rush", 16000, true, false); + // Give player speed buff + wielder.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, _speedDuration, _speedAmount)); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/KnightLance.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/KnightLance.java new file mode 100644 index 00000000..e147d44a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/KnightLance.java @@ -0,0 +1,234 @@ +package mineplex.game.clans.items.legendaries; + +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClansManager; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class KnightLance extends LegendaryItem +{ + private static final double CHARGE_VELOCITY = 1.5d; + private static final double MAX_BUILDUP_TICKS = 20 * 3; + + private boolean _charging; + private double _buildup; + + private transient final Set _hit = new HashSet<>(); //Avoid creating a new list every tick + + public KnightLance() + { + super("Knight's Greatlance", new String[] + { + C.cWhite + "Relic of a bygone age.", + C.cWhite + "Emblazoned with cryptic runes, this", + C.cWhite + "Lance bears the marks of its ancient master.", + C.cWhite + "You feel him with you always:", + C.cWhite + "Heed his warnings and stave off the darkness.", + " ", + C.cWhite + "Deals " + C.cYellow + "8 Damage" + C.cWhite + " with attack", + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Charge", + }, Material.RECORD_12); + } + + @Override + public void update(Player wielder) + { + boolean holding = isHoldingRightClick(); + + if (holding && !_charging) + { + if (canPropel(wielder)) + { + _buildup = 0; + _charging = true; + } + } + else if (!holding && _charging) + { + _charging = false; + _buildup = 0; + } + else if (_charging && !canPropel(wielder)) + { + _charging = false; + _buildup = 0; + } + + if (_charging) + { + for (Entity near : wielder.getNearbyEntities(0.6, 1, 0.6)) + { + if (near instanceof LivingEntity) + { + LivingEntity entity = (LivingEntity) near; + if (!canHit(wielder, entity)) + { + continue; + } + if (entity instanceof Horse) + { + _hit.add((LivingEntity)((Horse)entity).getPassenger()); + ((Horse)entity).eject(); + } + else + { + _hit.add(entity); + } + } + } + if (!_hit.isEmpty()) + { + _charging = false; + double damagePercentage = getBuildup() / MAX_BUILDUP_TICKS; + _buildup = 0; + + wielder.getWorld().playSound(wielder.getLocation(), Sound.ZOMBIE_METAL, 1.5f, 0.5f); + for (LivingEntity hit : _hit) + { + //Damage Event + ClansManager.getInstance().getDamageManager().NewDamageEvent(hit, wielder, null, + DamageCause.CUSTOM, 2 + (10 * damagePercentage), false, true, false, + wielder.getName(), "Knight's Greatlance Charge"); + + //Velocity + UtilAction.velocity(hit, + UtilAlg.getTrajectory2d(wielder.getLocation().toVector(), hit.getLocation().toVector()), + 2.6, true, 0, 0.2, 1.4, true); + + //Condition + ClansManager.getInstance().getCondition().Factory().Falling("Knight's Greatlance Charge", hit, wielder, 10, false, true); + } + _hit.clear(); + Recharge.Instance.useForce(wielder, "Knight Lance Charge Attack", 5000); + Recharge.Instance.recharge(wielder, "Knight Lance Charge CD Inform"); + return; + } + + propelPlayer(wielder); + UtilTextBottom.displayProgress(getBuildup() / MAX_BUILDUP_TICKS, wielder); + _buildup++; + } + } + + @Override + public void onUnequip(Player wielder) + { + _charging = false; + _buildup = 0; + } + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + event.AddMod("Knight's Greatlance", 7); + } + + private void propelPlayer(Player player) + { + Vector direction = player.getLocation().getDirection().normalize(); + direction.setY(0); + direction.multiply(CHARGE_VELOCITY); + + player.setVelocity(direction); + + UtilParticle.PlayParticle(ParticleType.CRIT, player.getLocation(), + (float)(Math.random() - 0.5), 0.2f + (float)(Math.random() * 1), (float)(Math.random() - 0.5), 0, 3, + ViewDist.LONG, UtilServer.getPlayers()); + } + + private boolean canPropel(Player player) + { + return UtilEnt.isGrounded(player) && + !UtilEnt.isInWater(player) && + player.getVehicle() == null && + !ClansManager.getInstance().getClanUtility().isSafe(player) && + Recharge.Instance.usable(player, "Knight Lance Charge Attack", Recharge.Instance.use(player, "Knight Lance Charge CD Inform", 1500, false, false)); + } + + private boolean canHit(Player player, LivingEntity entity) + { + if (UtilEnt.hasFlag(entity, "LegendaryAbility.IgnoreMe")) + { + return false; + } + if (ClansManager.getInstance().getClanUtility().isSafe(entity.getLocation())) + { + return false; + } + if (entity instanceof Horse) + { + Entity passenger = ((Horse)entity).getPassenger(); + if (passenger == null) + { + return false; + } + else + { + if (passenger instanceof LivingEntity) + { + if (!canHit(player, (LivingEntity)passenger)) + { + return false; + } + } + else + { + return false; + } + } + } + if (entity instanceof Player) + { + Player target = (Player) entity; + if (ClansManager.getInstance().hasTimer(target)) + { + return false; + } + if (ClansManager.getInstance().isInClan(player) && ClansManager.getInstance().getClan(player).isMember(target)) + { + return false; + } + if (target.getGameMode() == GameMode.CREATIVE || target.getGameMode() == GameMode.SPECTATOR) + { + return false; + } + if (ClansManager.getInstance().getIncognitoManager().Get(target).Hidden) + { + return false; + } + if (ClansManager.getInstance().isInClan(player) && ClansManager.getInstance().getClan(player).isAlly(ClansManager.getInstance().getClan(target))) + { + return false; + } + } + + return true; + } + + private double getBuildup() + { + return UtilMath.clamp(_buildup, 0d, MAX_BUILDUP_TICKS); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java new file mode 100644 index 00000000..27f476e0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java @@ -0,0 +1,107 @@ +package mineplex.game.clans.items.legendaries; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class LegendaryItem extends CustomItem +{ + private static final long BLOCK_COOLDOWN = 260L; // Right clicking activates right click for 260ms + + protected long _lastBlock; // Timestamp of last block from wielder + + public LegendaryItem(String name, String[] description, Material material) + { + super(name, description, material); + + _lastBlock = 0L; + } + + /* + * Leave implementation to potential subtypes + */ + public void update(Player wielder) {} + + /* + * Leave implementation to potential subtypes + */ + public void preUpdate(Player wielder) {} + + /* + * Leave implementation to potential subtypes + */ + public void onUnequip(Player wielder) {} + + /* + * Leave implementation to potential subtypes + */ + public void onAttack(CustomDamageEvent event, Player wielder) {} + + @Override + public void onAttack(CustomDamageEvent event) + { + if (event.GetDamagerPlayer(true) != null) + { + onAttack(event, event.GetDamagerPlayer(true)); + } + + super.onAttack(event); + } + + public void onInteract(PlayerInteractEvent event) + { + Action action = event.getAction(); + + if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK) + { + _lastBlock = System.currentTimeMillis(); + } + + super.onInteract(event); + } + + public boolean isHoldingRightClick() + { + return timeSinceLastBlock() <= BLOCK_COOLDOWN; + } + + public long timeSinceLastBlock() + { + return System.currentTimeMillis() - _lastBlock; + } + + protected void log(String message) + { + System.out.println("[Custom Item - " + _displayName + "] " + message); + } + + /** + * @param minValue - the minimum value for attribute value range + * @param maxValue - the maximum value for attribute value range + * @return newly instantiated {@link ValueDistribution} for attribute values in range [{@code minValue}. {@code maxValue}]. + */ + public static ValueDistribution generateDistribution(double minValue, double maxValue) + { + return new ValueDistribution(minValue, maxValue); + } + + /** + * Add a {@link PotionEffect} to {@code player} with specified {@code type}, {@code amplifier} (power) and + * {@code tickDuration} of the effect. + * @param player - the player to receive the potion effect + * @param type - the type of potion to apply + * @param tickDuration - the duration (in ticks) to apply the potion for + * @param amplifier - the amplifier (level/power, zero-based) of the potion effect + */ + public static void grantPotionEffect(Player player, PotionEffectType type, int tickDuration, int amplifier) + { + player.addPotionEffect(new PotionEffect(type, amplifier, tickDuration), true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticMaul.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticMaul.java new file mode 100644 index 00000000..3c2e34d8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticMaul.java @@ -0,0 +1,169 @@ +package mineplex.game.clans.items.legendaries; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.core.ClaimLocation; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class MagneticMaul extends LegendaryItem +{ + private static final double PULL_RANGE = 10d; + + private double _power; + private double _heat; + + public MagneticMaul() + { + super("Magnetic Maul", UtilText.splitLinesToArray(new String[] + { + C.cWhite + "For centuries, warlords used this hammer to control their subjects. This brutal weapon allows you to pull your enemies towards you with magnetic force!", + " ", + "#" + C.cWhite + "Deals " + C.cYellow + "8 Damage" + C.cWhite + " with attack", + "#" + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Magnetism" + }, LineFormat.LORE), Material.RECORD_5); + } + + @Override + public void update(Player wielder) + { + Location loc = wielder.getLocation(); + ClanTerritory territory = ClansManager.getInstance().getClaimMap().get(ClaimLocation.of(loc.getChunk())); + if (territory != null && territory.isSafe(loc)) + { + return; + } + if (ClansManager.getInstance().hasTimer(wielder)) + { + UtilPlayer.message(wielder, F.main("Clans", "You are not allowed to use the Magnetic Maul whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + + if (isHoldingRightClick()) + { + if (canPull()) + { + pullEntities(wielder); + } + } + else + { + addPower(Math.max(0, 0.65 - (_heat / 150))); + + if (_heat > 0) + { + _heat--; + } + } + + UtilTextBottom.displayProgress(_power / 80., wielder); + } + + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + event.AddKnockback("Magnetic Blade", -0.5d); // Pull players with negative knockback + event.AddMod("Magnetic Maul", 7); + log("Negative knockback!"); + } + + private void pullEntities(Player player) + { + Vector direction = player.getLocation().getDirection().normalize().multiply(10.0d); + Location target = player.getEyeLocation().add(direction); + + double targetDistance = player.getLocation().distance(target); + + for (LivingEntity entity : player.getWorld().getLivingEntities()) + { + if (entity.getEntityId() == player.getEntityId()) + { + continue; // Skip pulling self + } + if (entity.getPassenger() != null && entity.getPassenger().getEntityId() == player.getEntityId()) + { + continue; + } + if (UtilEnt.hasFlag(entity, "LegendaryAbility.IgnoreMe")) + { + continue; + } + + double otherDistance = player.getLocation().distance(entity.getLocation()); + double otherTargetDistance = target.distance(entity.getLocation()); + + // If player is in-front of us and within pulling range + if (otherTargetDistance < targetDistance && otherDistance <= PULL_RANGE) + { + // If entity is in safe zone, don't allow pulling of that entity. + if (ClansManager.getInstance().getClaimMap().containsKey(ClaimLocation.of(entity.getLocation().getChunk()))) + { + if (ClansManager.getInstance().getClaimMap().get(ClaimLocation.of(entity.getLocation().getChunk())).isSafe(entity.getLocation())) + { + continue; + } + } + + UtilAction.velocity(entity, UtilAlg.getTrajectory(entity, player), 0.3, false, 0, 0, 1, true); + } + } + + // Do Particles + for (int i = 0; i < 6; i++) + { + Vector random = new Vector(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2); + + Location origin = player.getLocation().add(0, 1.3, 0); + origin.add(player.getLocation().getDirection().multiply(10)); + origin.add(random); + + Vector vel = UtilAlg.getTrajectory(origin, player.getLocation().add(0, 1.3, 0)); + vel.multiply(7); + + UtilParticle.PlayParticle(ParticleType.MAGIC_CRIT, + origin, + (float)vel.getX(), + (float)vel.getY(), + (float)vel.getZ(), + 1, 0, ViewDist.LONG, UtilServer.getPlayers()); + } + + removePower(1.75); + _heat++; + } + + private void addPower(double power) + { + _power = UtilMath.clamp(_power + power, 0, 80); + } + + private void removePower(double power) + { + _power = UtilMath.clamp(_power - power, 0, 80); + } + + private boolean canPull() + { + return _power >= 10 && _heat < 70; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeridianScepter.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeridianScepter.java new file mode 100644 index 00000000..29268c8d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeridianScepter.java @@ -0,0 +1,323 @@ +package mineplex.game.clans.items.legendaries; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.RGBData; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilColor; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTime; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClansManager; + +public class MeridianScepter extends LegendaryItem +{ + private static final RGBData[] COLORS = { UtilColor.RgbPurple, UtilColor.RgbPurple.Lighten(), UtilColor.RgbPurple.Darken() }; + + private long _interactWait; + + private transient Map _animations = new HashMap<>(); + + public MeridianScepter() + { + super("Meridian Scepter", UtilText.splitLinesToArray(new String[] + { + C.cWhite + "Legend says that this scepter was retrieved from the deepest trench in all of Minecraftia. It is said that he who wields this scepter holds the power of Poseidon himself.", + " ", + "#" + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Meridian Beam" + }, LineFormat.LORE), Material.RECORD_6); + } + + @Override + public void update(Player wielder) + { + if (timeSinceLastBlock() < 98 && (System.currentTimeMillis() - _interactWait) >= 98) + { + if (ClansManager.getInstance().hasTimer(wielder)) + { + UtilPlayer.message(wielder, F.main("Clans", "You are not allowed to fire the Meridian Scepter whilst protected from PvP. Run " + F.elem("/pvp") + " to enable PvP!")); + return; + } + + if (ClansManager.getInstance().getClanUtility().getClaim(wielder.getLocation()) != null && ClansManager.getInstance().getClanUtility().getClaim(wielder.getLocation()).isSafe(wielder.getLocation())) + { + UtilPlayer.message(wielder, F.main("Clans", "You are not allowed to fire the " + F.elem("Meridian Scepter") + " whilst in a safe zone.")); + return; + } + + if (Recharge.Instance.use(wielder, "Meridian Scepter", 2000, true, true)) + { + fire(wielder); + + _interactWait = System.currentTimeMillis(); + } + } + } + + private void fire(final Player shooter) + { + final Location projectile = shooter.getEyeLocation(); + final Location origin = shooter.getEyeLocation(); + final Vector direction = shooter.getEyeLocation().getDirection().normalize().multiply(0.25); + final int maxRange = 50; + final int maxDings = maxRange * 4; + + UtilServer.repeat(new BukkitRunnable() + { + private int dingsDone; + private Location previousLocation = projectile; + + private void burst() + { + for (Entity cur : projectile.getWorld().getEntities()) + { + if (cur == shooter || !(cur instanceof LivingEntity) || (cur instanceof Player && UtilPlayer.isSpectator(cur)) || UtilEnt.hasFlag(cur, "LegendaryAbility.IgnoreMe")) + continue; + + LivingEntity ent = (LivingEntity) cur; + + // If they are less than 0.5 blocks away + if (ent.getEyeLocation().subtract(0, .3, 0).distance(projectile) <= 2) + { + AttackAnimation aa = new AttackAnimation(ent, shooter); + int i = UtilServer.getServer().getScheduler().scheduleSyncRepeatingTask(UtilServer.getPlugin(), () -> + { + aa.update(); + }, 0, 1); + _animations.put(aa, i); + + UtilPlayer.message(ent, F.main("Clans", F.elem(shooter.getName()) + " hit you with a " + F.elem("Meridian Scepter") + C.mBody + ".")); + UtilPlayer.message(shooter, F.main("Clans", "You hit " + F.elem(ent.getName()) + " with your " + F.elem("Meridian Scepter") + C.mBody + ".")); + } + } + + playParticle(projectile, previousLocation); + + cancel(); + } + + public void run() + { + if (dingsDone >= maxDings || !shooter.isOnline()) + { + burst(); + } + else + { + for (int i = 0; i < 2; i++) + { + Player closestPlayer = null; + double dist = 0; + + for (Player closest : UtilServer.getPlayers()) + { + if (!closest.getWorld().equals(projectile.getWorld())) + { + continue; + } + + if (ClansManager.getInstance().hasTimer(closest)) + { + continue; + } + + if (ClansManager.getInstance().isInClan(shooter) && ClansManager.getInstance().getClan(shooter).isMember(closest)) + { + continue; + } + + if (shooter.getGameMode().equals(GameMode.CREATIVE) || shooter.getGameMode().equals(GameMode.SPECTATOR)) + { + continue; + } + + if (closest.getGameMode().equals(GameMode.CREATIVE) || closest.getGameMode().equals(GameMode.SPECTATOR)) + { + continue; + } + + if (ClansManager.getInstance().getIncognitoManager().Get(closest).Hidden) + { + continue; + } + + if (ClansManager.getInstance().isInClan(shooter) && ClansManager.getInstance().getClan(shooter).isAlly(ClansManager.getInstance().getClan(closest))) + { + continue; + } + + if (ClansManager.getInstance().getClanUtility().getClaim(closest.getLocation()) != null && ClansManager.getInstance().getClanUtility().getClaim(closest.getLocation()).isSafe(closest.getLocation())) + { + continue; + } + + Location loc = closest.getLocation(); + + if (closest != shooter) + { + double dist1 = loc.distance(origin); + if (dist1 < maxRange + 10) + { + double dist2 = projectile.distance(loc); + if (closestPlayer == null || dist2 < dist) + { + double dist3 = projectile.clone().add(direction).distance(loc); + + if (dist3 < dist2) + { + closestPlayer = closest; + dist = dist2; + } + } + } + } + } + + if (closestPlayer != null) + { + Vector newDirection = closestPlayer.getLocation().add(0, 1, 0).toVector() + .subtract(projectile.toVector()); + + direction.add(newDirection.normalize().multiply(0.02)).normalize().multiply(0.25); + } + + projectile.add(direction); + + for (Entity cur : projectile.getWorld().getEntities()) + { + if (cur == shooter || !(cur instanceof LivingEntity) + || (cur instanceof Player && UtilPlayer.isSpectator(cur)) + || UtilEnt.hasFlag(cur, "LegendaryAbility.IgnoreMe")) + continue; + + LivingEntity ent = (LivingEntity) cur; + + Location eLoc = ent.getLocation(); + + // If they are less than 0.5 blocks away + if (eLoc.clone().add(0, projectile.getY() - eLoc.getY(), 0).distance(projectile) <= 0.7) + { + // If it is in their body height + if (Math.abs((eLoc.getY() + (ent.getEyeHeight() / 1.5)) - projectile.getY()) <= ent.getEyeHeight() / 2) + { + burst(); + return; + } + } + } + + if (UtilBlock.solid(projectile.getBlock())) + { + burst(); + return; + } + + playParticle(projectile, previousLocation); + previousLocation = projectile.clone(); + + dingsDone++; + } + + projectile.getWorld().playSound(projectile, Sound.BLAZE_BREATH, 0.2F, 1f); + } + } + }, 0); + } + + private void playParticle(Location start, Location end) + { + for (Location loc : UtilShapes.getLinesDistancedPoints(start, end, 0.06)) + { + UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, loc, UtilCollections.random(COLORS).ToVector(), 1f, 0, ViewDist.LONG); + } + } + + private class AttackAnimation + { + private LivingEntity _hit; + private Player _shooter; + private double _step; + private double _radius; + private long _start, _lastStepIncrease; + + public AttackAnimation(LivingEntity hit, Player shooter) + { + _step = 0; + _start = System.currentTimeMillis(); + _lastStepIncrease = System.currentTimeMillis(); + _hit = hit; + _shooter = shooter; + _radius = 2; + } + + public void update() + { + if (_hit == null || !_hit.isValid() || _hit.isDead() || ((_hit instanceof Player) && !((Player)_hit).isOnline())) + { + end(); + return; + } + if (UtilTime.elapsed(_lastStepIncrease, 500)) + { + _step++; + _lastStepIncrease = System.currentTimeMillis(); + } + drawHelix(); + + if (UtilTime.elapsed(_start, 2000)) + { + _hit.getWorld().strikeLightningEffect(_hit.getLocation()); + ClansManager.getInstance().getDamageManager().NewDamageEvent(_hit, _shooter, null, + DamageCause.CUSTOM, 8, false, true, true, + _shooter.getName(), "Meridian Scepter"); + ClansManager.getInstance().getCondition().Factory().Blind("Meridian Scepter", _hit, _shooter, 3, 0, true, true, false); + end(); + return; + } + } + + private void end() + { + int id = _animations.remove(this); + Bukkit.getScheduler().cancelTask(id); + } + + private void drawHelix() + { + double height = Math.min(_step * 2, 8D); + + for (double y = 0; y <= height; y += .5) + { + double x = _radius * Math.cos(y); + double z = _radius * Math.sin(y); + Location play = _hit.getLocation().add(x, y, z); + + UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, play, null, 0, 3, ViewDist.MAX); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java new file mode 100644 index 00000000..8a815479 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java @@ -0,0 +1,40 @@ +package mineplex.game.clans.items.legendaries; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +public class MeteorBow extends LegendaryItem +{ + public static final int MAX_FLIGHT_TIME = 80; // Max flight of 80 ticks + + private long _flightTime; // Time (in ticks) since last touching ground and flying + + public MeteorBow() + { + super("Meteor Bow", new String[] + { + "Shoot explosive arrows!" + }, Material.BOW); + _flightTime = 0; + } + + @Override + public void update(Player wielder) + { + if (isHoldingRightClick() && canPropel()) + { + propelPlayer(wielder); + } + } + + private void propelPlayer(Player player) + { + _flightTime++; + // TODO: Propel player forward with ??? velocity + } + + private boolean canPropel() + { + return _flightTime <= MAX_FLIGHT_TIME; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java new file mode 100644 index 00000000..2558a0d2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java @@ -0,0 +1,205 @@ +package mineplex.game.clans.items.legendaries; + +import java.lang.reflect.Field; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +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.recharge.Recharge; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.PlayerGear; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import net.minecraft.server.v1_8_R3.PlayerConnection; + +public class WindBlade extends LegendaryItem +{ + private static final Field G_FIELD; + + static + { + try + { + G_FIELD = PlayerConnection.class.getDeclaredField("g"); + G_FIELD.setAccessible(true); + } + catch (ReflectiveOperationException exception) + { + throw new RuntimeException("Could not reflectively access field", exception); + } + + UtilServer.RegisterEvents(new Listener() + { + @EventHandler + public void onFall(CustomDamageEvent event) + { + if (event.GetDamageePlayer() != null && event.GetCause() == EntityDamageEvent.DamageCause.FALL) + { + PlayerGear playerGear = GearManager.getInstance().getPlayerGear(event.GetDamageePlayer()); + if (playerGear.getWeapon() instanceof WindBlade) + { + event.SetCancelled("Wind Blade No Fall Damage"); + } + } + } + }); + } + + private static final double FLIGHT_VELOCITY = 0.75d; + + private double _power; + private double _burnoutThreshold; + + private int _messageTimer; + + public WindBlade() + { + super("Wind Blade", new String[] + { + C.cWhite + "Long ago, a race of cloud dwellers", + C.cWhite + "terrorized the skies. A remnant of", + C.cWhite + "their tyranny, this airy blade is", + C.cWhite + "the last surviving memorium from", + C.cWhite + "their final battle against the Titans.", + " ", + C.cWhite + "Deals " + C.cYellow + "7 Damage" + C.cWhite + " with attack", + C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Flight", + }, Material.GREEN_RECORD); + } + + @Override + public void update(Player wielder) + { + long burnoutRemaining = -1L; + + if (Recharge.Instance.Get(wielder) != null && Recharge.Instance.Get(wielder).containsKey("clans_legendary_windblade_burnout")) + { + burnoutRemaining = Recharge.Instance.Get(wielder).get("clans_legendary_windblade_burnout").GetRemaining(); + } + + // Check if player is attempting to fly and activate + if (isHoldingRightClick()) + { + if (canPropel(wielder)) + { + wielder.setFallDistance(0f); + + if (burnoutRemaining > 0) + { + _messageTimer++; + + if (_messageTimer % 4 == 0) + { + UtilParticle.PlayParticle(ParticleType.SMOKE, wielder.getLocation(), 0.f, 0.f, 0.f, .1f, 1, ViewDist.NORMAL); + wielder.playSound(wielder.getLocation(), Sound.FIZZ, .5f, 1.f); + + removePower(0.15); + + _burnoutThreshold = 0; + } + + if (_messageTimer % 5 == 0) + { + UtilPlayer.message(wielder, F.main("Wind Blade", "Flight power damaged whilst scraping the ground! Repairs will be finish in " + F.time(UtilTime.MakeStr(burnoutRemaining)) + ".")); + } + + if (_messageTimer % 10 == 0) + { + wielder.playSound(wielder.getLocation(), Sound.ANVIL_USE, .5f, 1.5f); + } + + return; + } + + removePower(UtilEnt.isGrounded(wielder) ? 1.17 : .88); + + propelPlayer(wielder); + UtilParticle.PlayParticle(ParticleType.EXPLODE, wielder.getLocation().add(0, 1, 0), 0, 0, 0, .1f, 3, ViewDist.NORMAL); + + wielder.playSound(wielder.getLocation(), Sound.FIRE, .25f, 1.75f); + } + + if (UtilEnt.isGrounded(wielder)) + { + _burnoutThreshold++; + wielder.playSound(wielder.getLocation(), Sound.NOTE_STICKS, .75f, 2.f); + } + else + { + _burnoutThreshold = 0; + } + } + else + { + _burnoutThreshold = UtilMath.clamp(_burnoutThreshold - .5, 0, _burnoutThreshold); + } + + if (UtilEnt.isGrounded(wielder, wielder.getLocation()) || UtilEnt.isGrounded(wielder, wielder.getLocation().subtract(0, 1, 0))) + { + addPower(0.65); + } + + if (_burnoutThreshold > 15 && burnoutRemaining <= 0) + { + Recharge.Instance.use(wielder, "clans_legendary_windblade_burnout", 2500, false, false); + } + + UtilTextBottom.displayProgress(UtilMath.clamp(_power, .0, 80.) / 80., wielder); + } + + @Override + public void onAttack(CustomDamageEvent event, Player wielder) + { + event.AddMod("Wind Blade", 6); + } + + private void propelPlayer(Player player) + { + Vector direction = player.getLocation().getDirection().normalize(); + direction.multiply(FLIGHT_VELOCITY); + + player.setVelocity(direction); + + PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection; + try + { + G_FIELD.set(connection, 0); + } + catch (IllegalAccessException e) + { + new RuntimeException("Could not update g field", e).printStackTrace(); + } + } + + private boolean canPropel(Player player) + { + return _power > 0 && !UtilItem.isLiquid(player.getLocation().getBlock().getType()); + } + + private void addPower(double power) + { + _power = UtilMath.clamp(_power + power, -20, 80); + } + + private void removePower(double power) + { + _power = UtilMath.clamp(_power - power, -20, 80); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/Crossbow.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/Crossbow.java new file mode 100644 index 00000000..99b983de --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/Crossbow.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.items.rares; + +import org.bukkit.Material; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilText; +import mineplex.core.recharge.Recharge; + +public class Crossbow extends RareItem +{ + private static final Material LOADED_TYPE = Material.COMMAND_MINECART; + private static final Material UNLOADED_TYPE = Material.RECORD_6; + + private long _lastFire = System.currentTimeMillis(); + private long _interactWait; + + public Crossbow() + { + super("Crossbow", UtilText.splitLinesToArray(new String[] { + "#" + C.cYellow + "Right-Click" + C.cWhite + " to fire Crossbow." + }, LineFormat.LORE), UNLOADED_TYPE); + } + + @Override + public void update(Player wielder) + { + if (UtilInv.contains(wielder, Material.ARROW, (byte) 0, 1)) + { + wielder.getItemInHand().setType(LOADED_TYPE); + } + else + { + wielder.getItemInHand().setType(UNLOADED_TYPE); + } + + if ((System.currentTimeMillis() - _lastBlock) < 98 && (System.currentTimeMillis() - _interactWait) >= 98) + { + if (UtilInv.remove(wielder, Material.ARROW, (byte) 0, 1)) + { + if (Recharge.Instance.use(wielder, "Crossbow", 4000, true, true)) + { + fire(wielder); + + _interactWait = System.currentTimeMillis(); + } + } + } + } + + private void fire(final Player player) + { + Arrow arrow = player.shootArrow(); + + arrow.setShooter(player); + + _lastFire = System.currentTimeMillis(); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/RareItem.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/RareItem.java new file mode 100644 index 00000000..a986b184 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/RareItem.java @@ -0,0 +1,98 @@ +package mineplex.game.clans.items.rares; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class RareItem extends CustomItem +{ + public final long BLOCK_COOLDOWN = 200l; // Right clicking activates right click for 200ms + + protected long _lastBlock; // Timestamp of last block from wielder + public long timeSinceLastBlock() { return System.currentTimeMillis() - _lastBlock; } + + public RareItem(String name, String[] description, Material material) + { + super(name, description, material); + + _lastBlock = 0l; + } + + public void update(Player wielder) + { + // Leave implementation to potential subtypes + } + + public void preUpdate(Player wielder) + { + } + + public void onAttack(CustomDamageEvent event, Player wielder) + { + // Leave implementation to potential subtypes + } + + @Override + public void onAttack(CustomDamageEvent event) + { + if (event.GetDamagerPlayer(true) != null) + { + onAttack(event, event.GetDamagerPlayer(true)); + } + + super.onAttack(event); + } + + public void onInteract(PlayerInteractEvent event) + { + Action action = event.getAction(); + + if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK) + { + _lastBlock = System.currentTimeMillis(); + } + + super.onInteract(event); + } + + public boolean isHoldingRightClick() + { + return timeSinceLastBlock() <= BLOCK_COOLDOWN; + } + + protected void log(String message) + { + System.out.println("[Custom Item - " + _displayName + "] " + message); + } + + /** + * @param minValue - the minimum value for attribute value range + * @param maxValue - the maximum value for attribute value range + * @return newly instantiated {@link ValueDistribution} for attribute values in range [{@code minValue}. {@code maxValue}]. + */ + public static ValueDistribution generateDistribution(double minValue, double maxValue) + { + return new ValueDistribution(minValue, maxValue); + } + + /** + * Add a {@link PotionEffect} to {@code player} with specified {@code type}, {@code amplifier} (power) and + * {@code tickDuration} of the effect. + * @param player - the player to receive the potion effect + * @param type - the type of potion to apply + * @param tickDuration - the duration (in ticks) to apply the potion for + * @param amplifier - the amplifier (level/power, zero-based) of the potion effect + */ + public static void grantPotionEffect(Player player, PotionEffectType type, int tickDuration, int amplifier) + { + player.removePotionEffect(type); + player.addPotionEffect(new PotionEffect(type, amplifier, tickDuration)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/RunedPickaxe.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/RunedPickaxe.java new file mode 100644 index 00000000..99f1b206 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/rares/RunedPickaxe.java @@ -0,0 +1,197 @@ +package mineplex.game.clans.items.rares; + +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.LineFormat; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilText; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.core.repository.ClanTerritory; +import mineplex.game.clans.items.PlayerGear; + +public class RunedPickaxe extends RareItem +{ + private long _instamineEnabled; + private boolean _enabled; + + static + { + UtilServer.RegisterEvents(new Listener() + { + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + UtilServer.getPlayersCollection().forEach(player -> + { + PlayerGear gear = ClansManager.getInstance().getGearManager().getPlayerGear(player); + + if (!(gear.getWeapon() instanceof RunedPickaxe)) + { + return; + } + + RunedPickaxe pick = (RunedPickaxe) gear.getWeapon(); + + if (pick._enabled && !UtilTime.elapsed(pick._instamineEnabled, 12000)) + { + UtilTextBottom.displayProgress("Instant mine", (((double) (((double) System.currentTimeMillis()) - ((double) pick._instamineEnabled))) / 12000D), null, true, player); + } + + if (pick._enabled && (System.currentTimeMillis() - pick._instamineEnabled) >= 12000) + { + Recharge.Instance.use(player, "Instant Mine", 15 * 1000, true, true); + + pick._enabled = false; + } + + if (!pick._enabled) + { + player.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, 20 * 2, 100)); + } + }); + } + + @EventHandler + public void onSwap(PlayerItemHeldEvent event) + { + if (event.getPlayer().hasPotionEffect(PotionEffectType.FAST_DIGGING)) + { + ItemStack previous = event.getPlayer().getInventory().getItem(event.getPreviousSlot()); + if (previous != null && previous.getType() == Material.RECORD_7) + { + event.getPlayer().removePotionEffect(PotionEffectType.FAST_DIGGING); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void blockDamage(BlockDamageEvent event) + { + PlayerGear gear = ClansManager.getInstance().getGearManager().getPlayerGear(event.getPlayer()); + + if (!(gear.getWeapon() instanceof RunedPickaxe)) + { + return; + } + + RunedPickaxe pick = (RunedPickaxe) gear.getWeapon(); + + String playerClan = ClansManager.getInstance().getClanUtility().getClanByPlayer(event.getPlayer()) == null ? null : ClansManager.getInstance().getClanUtility().getClanByPlayer(event.getPlayer()).getName(); + + ClanTerritory territory = ClansManager.getInstance().getClanUtility().getClaim(event.getBlock().getLocation()); + + if (territory != null && !territory.Owner.equals(playerClan)) + return; + + if (event.getBlock().getType() == Material.BEDROCK || event.getBlock().getType() == Material.BARRIER) + return; + + if (ClansManager.getInstance().getNetherManager().getNetherWorld().equals(event.getBlock().getWorld())) + return; + + if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(event.getBlock().getLocation())) + return; + + if (ClansManager.getInstance().getBlockRestore().contains(event.getBlock())) + return; + + if (ClansManager.getInstance().getSiegeManager().getOutpostManager().getOutposts().stream().filter(outpost -> + { + return UtilAlg.inBoundingBox(event.getBlock().getLocation(), outpost.getBoundsBlockBreak().getLeft(), outpost.getBoundsBlockBreak().getRight()); + }).findAny().isPresent()) + return; + + if (!UtilTime.elapsed(pick._instamineEnabled, 12000)) + { + event.getBlock().breakNaturally(); + + event.getBlock().getWorld().playEffect(event.getBlock().getLocation(), Effect.TILE_BREAK, event.getBlock().getTypeId(), 10); + + event.getPlayer().playSound(event.getBlock().getLocation(), Sound.LAVA_POP, 1.f, 1.f); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void blockBreak(BlockBreakEvent event) + { + PlayerGear gear = ClansManager.getInstance().getGearManager().getPlayerGear(event.getPlayer()); + + if (!(gear.getWeapon() instanceof RunedPickaxe)) + { + return; + } + + RunedPickaxe pick = (RunedPickaxe) gear.getWeapon(); + + if (ClansManager.getInstance().getNetherManager().getNetherWorld().equals(event.getBlock().getWorld())) + return; + + if (ClansManager.getInstance().getBlockRestore().contains(event.getBlock())) + return; + + if (ClansManager.getInstance().getWorldEvent().getRaidManager().isInRaid(event.getBlock().getLocation())) + return; + + if (!pick._enabled) + { + event.setCancelled(true); + event.getBlock().breakNaturally(); + } + } + }); + } + + public RunedPickaxe() + { + super("Runed Pickaxe", UtilText.splitLinesToArray(new String[] + { + "What an interesting design this pickaxe seems to have!", + C.cYellow + "Right-Click" + C.cWhite + " to use " + F.elem("Instant mine") + "." + }, LineFormat.LORE), Material.RECORD_7); + } + + public void onInteract(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R)) + { + return; + } + + if (Recharge.Instance.usable(event.getPlayer(), "Instant Mine", true) && UtilTime.elapsed(_instamineEnabled, 15000)) + { + UtilTextMiddle.display("", "Instant mine enabled for " + F.elem("12 Seconds"), 20, 80, 20, event.getPlayer()); + _instamineEnabled = System.currentTimeMillis(); + _enabled = true; + } + + super.onInteract(event); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/runes/RuneManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/runes/RuneManager.java new file mode 100644 index 00000000..d7364864 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/runes/RuneManager.java @@ -0,0 +1,409 @@ +package mineplex.game.clans.items.runes; + +import java.util.Arrays; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.attributes.armor.ConqueringArmorAttribute; +import mineplex.game.clans.items.attributes.armor.LavaAttribute; +import mineplex.game.clans.items.attributes.armor.PaddedAttribute; +import mineplex.game.clans.items.attributes.armor.ReinforcedAttribute; +import mineplex.game.clans.items.attributes.armor.SlantedAttribute; +import mineplex.game.clans.items.attributes.bow.HeavyArrowsAttribute; +import mineplex.game.clans.items.attributes.bow.HuntingAttribute; +import mineplex.game.clans.items.attributes.bow.InverseAttribute; +import mineplex.game.clans.items.attributes.bow.LeechingAttribute; +import mineplex.game.clans.items.attributes.bow.RecursiveAttribute; +import mineplex.game.clans.items.attributes.bow.ScorchingAttribute; +import mineplex.game.clans.items.attributes.bow.SlayingAttribute; +import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute; +import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; +import mineplex.game.clans.items.attributes.weapon.FrostedAttribute; +import mineplex.game.clans.items.attributes.weapon.HasteAttribute; +import mineplex.game.clans.items.attributes.weapon.JaggedAttribute; +import mineplex.game.clans.items.attributes.weapon.SharpAttribute; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; + +/** + * Manager class for runes + */ +public class RuneManager implements Listener +{ + private static final String RUNE_NAME = C.cGold + "Ancient Rune"; + private String _managerName; + + public RuneManager(String name, JavaPlugin plugin) + { + _managerName = name; + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + /** + * Checks if an item is a rune + * @param item The item to check + * @return Whether the item is a rune + */ + public boolean isRune(ItemStack item) + { + if (item == null || item.getType() == Material.AIR) + { + return false; + } + ItemMeta im = item.getItemMeta(); + return im.hasDisplayName() && im.getDisplayName().equals(RUNE_NAME) && im.hasLore() && im.getLore().size() > 0; + } + + /** + * Converts a rune item to a rune attribute + * @param rune The rune to convert + * @return The attribute of the rune + */ + public RuneAttribute decodeRune(ItemStack rune) + { + if (!isRune(rune)) + { + return null; + } + RuneAttribute attribute = RuneAttribute.getFromDisplay(rune.getItemMeta().getLore().get(0)); + + return attribute; + } + + /** + * Gets the item representation of a rune attribute + * @param attribute The rune attribute to generate the rune from + * @return The item representation of the rune attribute + */ + public ItemStack getRune(RuneAttribute attribute) + { + ItemStack rune = new ItemStack(Material.NETHER_STAR); + ItemMeta im = rune.getItemMeta(); + + im.setDisplayName(RUNE_NAME); + im.setLore(Arrays.asList(attribute.getDisplay())); + rune.setItemMeta(im); + + return rune; + } + + /** + * Applies a rune to an item + * @param rune The rune to apply to the item + * @param to The item to apply the rune to + * @return The item after having the rune applied + */ + public ItemStack applyToItem(RuneAttribute rune, ItemStack to) + { + if (!rune.canApplyTo(to.getType())) + { + return null; + } + if (GearManager.isCustomItem(to)) + { + try + { + ItemAttribute attribute = rune.getAttributeClass().newInstance(); + CustomItem item = GearManager.parseItem(to); + if (!item.getAttributes().getRemainingTypes().contains(attribute.getType())) + { + return null; + } + item.getAttributes().addAttribute(attribute); + ItemStack stack = to.clone(); + item.setMaterial(stack.getType()); + item.update(stack); + return stack; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + else + { + try + { + CustomItem item = new CustomItem(to.getType()); + item.addDullEnchantment(); + ItemAttribute attribute = rune.getAttributeClass().newInstance(); + item.getAttributes().addAttribute(attribute); + ItemStack stack = to.clone(); + item.update(stack); + return stack; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onMakeBeaconWithRune(PrepareItemCraftEvent event) + { + if (event.getInventory().getResult() == null || !event.getInventory().getResult().getType().equals(Material.BEACON)) + { + return; + } + if (!isRune(event.getInventory().getItem(5))) + { + return; + } + event.getInventory().setResult(null); + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onCraftBeaconWithRune(CraftItemEvent event) + { + if (event.getInventory().getResult() == null || event.getInventory().getResult().getType() != Material.BEACON) + { + return; + } + if (!isRune(event.getInventory().getItem(5))) + { + return; + } + event.setCancelled(true); + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onPlaceRuneInAnvil(InventoryClickEvent event) + { + if (!(event.getWhoClicked() instanceof Player)) + { + return; + } + if (!event.getInventory().getType().equals(InventoryType.ANVIL)) + { + return; + } + if (!isRune(event.getCursor()) && !isRune(event.getCurrentItem())) + { + return; + } + event.setCancelled(true); + if (event.getInventory().getItem(0) == null && event.getInventory().getItem(1) == null) + { + event.getWhoClicked().closeInventory(); + } + UtilPlayer.message(event.getWhoClicked(), F.main(_managerName, "To use a rune, place it on an item!")); + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onUseRune(InventoryClickEvent event) + { + if(!(event.getWhoClicked() instanceof Player)) + { + return; + } + + Player player = (Player) event.getWhoClicked(); + + if (!isRune(event.getCursor())) + { + return; + } + if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR) + { + return; + } + + RuneAttribute rune = decodeRune(event.getCursor()); + if (rune == null) + { + return; + } + if (event.getCurrentItem().getAmount() > 1) + { + UtilPlayer.message(player, F.main(_managerName, "The rune cannot apply to all of those items!")); + return; + } + if (!rune.canApplyTo(event.getCurrentItem().getType())) + { + UtilPlayer.message(player, F.main(_managerName, "The rune seems to reject that type of item!")); + return; + } + ItemStack after = applyToItem(rune, event.getCurrentItem()); + if (after == null) + { + UtilPlayer.message(player, F.main(_managerName, "The rune seems to reject that item!")); + return; + } + + event.setCancelled(true); + ItemStack cursorAfter = null; + if (event.getCursor().getAmount() > 1) + { + cursorAfter = event.getCursor().clone(); + cursorAfter.setAmount(cursorAfter.getAmount() - 1); + } + event.setCursor(new ItemStack(Material.AIR)); + event.getClickedInventory().setItem(event.getSlot(), after); + if (cursorAfter != null) + { + UtilInv.insert(player, cursorAfter); + } + player.playSound(player.getLocation(), Sound.ANVIL_USE, 1.5f, 5f); + + player.updateInventory(); + } + + /** + * Enum of all rune attributes + */ + public static enum RuneAttribute + { + FROSTED(FrostedAttribute.class, "Frosted", true, false, false), + SHARP(SharpAttribute.class, "Sharp", true, false, false), + JAGGED(JaggedAttribute.class, "Jagged", true, false, false), + HASTE(HasteAttribute.class, "Haste", true, false, false), + FLAMING(FlamingAttribute.class, "Flaming", true, false, false), + CONQUERING(ConqueringAttribute.class, "Conquering", true, false, false), + SLANTED(SlantedAttribute.class, "Slanted", false, true, false), + REINFORCED(ReinforcedAttribute.class, "Reinforced", false, true, false), + CONQUERING_ARMOR(ConqueringArmorAttribute.class, "Conquering", false, true, false), + PADDED(PaddedAttribute.class, "Padded", false, true, false), + LAVA(LavaAttribute.class, "Lava Forged", false, true, false), + HEAVY(HeavyArrowsAttribute.class, "Heavy", false, false, true), + HUNTING(HuntingAttribute.class, "Hunting", false, false, true), + INVERSE(InverseAttribute.class, "Inverse", false, false, true), + LEECHING(LeechingAttribute.class, "Leeching", false, false, true), + RECURSIVE(RecursiveAttribute.class, "Recursive", false, false, true), + SCORCHING(ScorchingAttribute.class, "Scorching", false, false, true), + SLAYING(SlayingAttribute.class, "Slaying", false, false, true) + ; + + private Class _class; + private String _display; + private boolean _weapon, _armor, _bow; + + private RuneAttribute(Class attributeClass, String display, boolean weapon, boolean armor, boolean bow) + { + _class = attributeClass; + _display = display; + _weapon = weapon; + _armor = armor; + _bow = bow; + + if (weapon) + { + _display = C.cRed + C.Italics + _display; + } + if (armor) + { + _display = C.cGreen + C.Italics + _display; + } + if (bow) + { + _display = C.cDAqua + C.Italics + _display; + } + } + + /** + * Gets the lore display of this rune type + * @return The lore display of this rune type + */ + public String getDisplay() + { + return _display; + } + + /** + * Gets the class for this rune type + * @return The class for this rune type + */ + public Class getAttributeClass() + { + return _class; + } + + /** + * Checks whether this rune type can be applied to an item type + * @param type The item type to check + * @return Whether this rune type can be applied to that item type + */ + public boolean canApplyTo(Material type) + { + if (_weapon) + { + if (UtilItem.isSword(type) || UtilItem.isAxe(type)) + { + return true; + } + if (type == Material.RECORD_4 || type == Material.GOLD_RECORD || type == Material.RECORD_3 || type == Material.RECORD_5 || type == Material.GREEN_RECORD || type == Material.RECORD_12) + { + return true; + } + } + if (_armor && UtilItem.isArmor(type)) + { + return true; + } + if (_bow && type == Material.BOW) + { + return true; + } + + return false; + } + + /** + * Gets the rune attribute from a given lore display + * @param display The lore display to check + * @return The rune attribute associated with that lore display + */ + public static RuneAttribute getFromDisplay(String display) + { + for (RuneAttribute rune : RuneAttribute.values()) + { + if (rune.getDisplay().equals(display)) + { + return rune; + } + } + + return null; + } + + /** + * Gets the rune attribute that resolves to the given string + * @param string The string to get the rune attribute based on + * @return The rune attribute that resolves to that string + */ + public static RuneAttribute getFromString(String string) + { + for (RuneAttribute rune : RuneAttribute.values()) + { + if (rune.toString().equalsIgnoreCase(string)) + { + return rune; + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/smelting/Smelter.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/smelting/Smelter.java new file mode 100644 index 00000000..d7eb12c4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/smelting/Smelter.java @@ -0,0 +1,119 @@ +package mineplex.game.clans.items.smelting; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.items.GearManager; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class Smelter +{ + + public static void smeltItemInHand(Player player) + { + ItemStack item = player.getInventory().getItemInHand(); + + if (isSmeltable(item)) + { + ItemStack returns = smeltItem(item); + player.getInventory().setItemInHand(returns); + } + + notify(player, "You have successfully smelted your item!"); + } + + public static ItemStack smeltItem(ItemStack item) + { + Material material = getSmeltedType(item.getType()); + int maxAmount = getSmeltAmount(item.getType()); + int amount = maxAmount; + + if (!GearManager.isCustomItem(item)) + { + short maxDurability = item.getType().getMaxDurability(); + int durability = maxDurability - item.getDurability(); + double percent = durability / (double) maxDurability; + System.out.println("Durability: " + item.getDurability() + " -- max: " + item.getType().getMaxDurability() + " --- percent: " + percent); + amount = Math.max(1, (int) (maxAmount * percent)); + } + + return new ItemStack(material, amount); + } + + private static int getSmeltAmount(Material itemType) + { + switch (itemType) + { + case IRON_BOOTS: + case DIAMOND_BOOTS: + case GOLD_BOOTS: + return 4; + case IRON_HELMET: + case DIAMOND_HELMET: + case GOLD_HELMET: + return 5; + case IRON_LEGGINGS: + case DIAMOND_LEGGINGS: + case GOLD_LEGGINGS: + return 7; + case IRON_CHESTPLATE: + case DIAMOND_CHESTPLATE: + case GOLD_CHESTPLATE: + return 8; + case IRON_SWORD: + case DIAMOND_SWORD: + case GOLD_SWORD: + return 2; + case IRON_AXE: + case DIAMOND_AXE: + case GOLD_AXE: + return 3; + default: + return 0; + } + } + + private static boolean isSmeltable(ItemStack item) + { + if (item == null) return false; + + return getSmeltedType(item.getType()) != null; + } + + private static Material getSmeltedType(Material itemType) + { + switch (itemType) + { + case IRON_BOOTS: + case IRON_LEGGINGS: + case IRON_CHESTPLATE: + case IRON_HELMET: + case IRON_SWORD: + case IRON_AXE: + return Material.IRON_ORE; + case DIAMOND_BOOTS: + case DIAMOND_LEGGINGS: + case DIAMOND_CHESTPLATE: + case DIAMOND_HELMET: + case DIAMOND_SWORD: + case DIAMOND_AXE: + return Material.DIAMOND_ORE; + case GOLD_BOOTS: + case GOLD_LEGGINGS: + case GOLD_CHESTPLATE: + case GOLD_HELMET: + case GOLD_SWORD: + case GOLD_AXE: + return Material.GOLD_ORE; + default: + return null; + } + } + + private static void notify(Player player, String message) + { + UtilPlayer.message(player, F.main("Smelter", message)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/smelting/SmeltingListener.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/smelting/SmeltingListener.java new file mode 100644 index 00000000..3d5afd6a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/smelting/SmeltingListener.java @@ -0,0 +1,34 @@ +package mineplex.game.clans.items.smelting; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Listens for smelting related events triggered by players to carry out + * item smelting for base resources and ores. + * @author MrTwiggy + * + */ +public class SmeltingListener implements Listener +{ + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) + { + if (event.getAction() == Action.LEFT_CLICK_BLOCK && event.getPlayer().isSneaking()) + { + Block clicked = event.getClickedBlock(); + + if (clicked.getType() == Material.FURNACE) + { + Smelter.smeltItemInHand(event.getPlayer()); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java new file mode 100644 index 00000000..201f8997 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearPage.java @@ -0,0 +1,791 @@ +package mineplex.game.clans.items.ui; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.text.WordUtils; +import org.apache.commons.lang3.tuple.Triple; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilCollections; +import mineplex.core.common.util.UtilUI; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.ItemType; +import mineplex.game.clans.items.RareItemFactory; +import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.game.clans.items.attributes.armor.ConqueringArmorAttribute; +import mineplex.game.clans.items.attributes.armor.LavaAttribute; +import mineplex.game.clans.items.attributes.armor.PaddedAttribute; +import mineplex.game.clans.items.attributes.armor.ReinforcedAttribute; +import mineplex.game.clans.items.attributes.armor.SlantedAttribute; +import mineplex.game.clans.items.attributes.bow.HeavyArrowsAttribute; +import mineplex.game.clans.items.attributes.bow.HuntingAttribute; +import mineplex.game.clans.items.attributes.bow.InverseAttribute; +import mineplex.game.clans.items.attributes.bow.LeechingAttribute; +import mineplex.game.clans.items.attributes.bow.RecursiveAttribute; +import mineplex.game.clans.items.attributes.bow.ScorchingAttribute; +import mineplex.game.clans.items.attributes.bow.SlayingAttribute; +import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute; +import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; +import mineplex.game.clans.items.attributes.weapon.FrostedAttribute; +import mineplex.game.clans.items.attributes.weapon.HasteAttribute; +import mineplex.game.clans.items.attributes.weapon.JaggedAttribute; +import mineplex.game.clans.items.attributes.weapon.SharpAttribute; +import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.DemonicScythe; +import mineplex.game.clans.items.legendaries.GiantsBroadsword; +import mineplex.game.clans.items.legendaries.HyperAxe; +import mineplex.game.clans.items.legendaries.KnightLance; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.game.clans.items.legendaries.MagneticMaul; +import mineplex.game.clans.items.legendaries.MeridianScepter; +import mineplex.game.clans.items.legendaries.WindBlade; +import mineplex.game.clans.items.rares.RareItem; +import mineplex.game.clans.items.rares.RunedPickaxe; + +public class GearPage extends ShopPageBase +{ + private int _stage = 0; + + private RareItemFactory _factory; + + private final IButton _nextButton; + private final IButton _backButton; + + private Class _superPrefix; + private Class _prefix; + private Class _suffix; + + private List> _armorSuperPrefixes; + private List> _armorPrefixes; + private List> _armorSuffixes; + + private List> _weaponSuperPrefixes; + private List> _weaponPrefixes; + private List> _weaponSuffixes; + + private List> _bowSuperPrefixes; + private List> _bowPrefixes; + private List> _bowSuffixes; + + private List> _legendaryItems; + private List> _rareItems; + + private List _weaponTypes; + private List _armorTypes; + + public GearPage(final GearManager gearManager, final GearShop shop, final CoreClientManager clientManager, final DonationManager donationManager, final String name, final Player player) + { + super(gearManager, shop, clientManager, donationManager, name, player); + + _nextButton = new IButton() + { + public void onClick(final Player player, final ClickType clickType) + { + performNext(); + } + }; + + _backButton = new IButton() + { + public void onClick(final Player player, final ClickType clickType) + { + performBack(); + } + }; + + _legendaryItems = Arrays.> asList(MeridianScepter.class, AlligatorsTooth.class, WindBlade.class, GiantsBroadsword.class, HyperAxe.class, MagneticMaul.class, DemonicScythe.class, KnightLance.class); + + _rareItems = Arrays.> asList(RunedPickaxe.class); + + _armorSuperPrefixes = Arrays.> asList(LavaAttribute.class); + _armorPrefixes = Arrays.> asList(PaddedAttribute.class, ReinforcedAttribute.class, SlantedAttribute.class); + _armorSuffixes = Arrays.> asList(ConqueringArmorAttribute.class); + + _weaponSuperPrefixes = Arrays.> asList(FlamingAttribute.class, FrostedAttribute.class); + _weaponPrefixes = Arrays.> asList(JaggedAttribute.class, SharpAttribute.class); + _weaponSuffixes = Arrays.> asList(ConqueringAttribute.class, HasteAttribute.class); + + _bowSuperPrefixes = Arrays.> asList(LeechingAttribute.class, ScorchingAttribute.class); + _bowPrefixes = Arrays.> asList(HeavyArrowsAttribute.class, HuntingAttribute.class, InverseAttribute.class, RecursiveAttribute.class); + _bowSuffixes = Arrays.> asList(SlayingAttribute.class); + + _armorTypes = Arrays.asList(Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS, Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS); + _weaponTypes = Arrays.asList(Material.DIAMOND_SWORD, Material.DIAMOND_AXE, Material.IRON_SWORD, Material.IRON_AXE, Material.GOLD_SWORD, Material.GOLD_AXE, Material.STONE_SWORD, Material.STONE_AXE); + + buildPage(); + } + + protected void buildPage() + { + clearPage(); + + String stageTitle = "Fatal Error"; + Material stageMaterial = Material.WOOL; + + try + { + if (_stage == 0) + { + Pair stage1 = doStageOne(); + + stageTitle = stage1.getLeft(); + if (stage1.getRight() != null) + { + stageMaterial = stage1.getRight(); + } + } + else if (_stage == 1) + { + Triple stage2 = doStageTwo(); + + if (stage2.getLeft()) + { + return; + } + + stageTitle = stage2.getMiddle(); + if (stage2.getRight() != null) + { + stageMaterial = stage2.getRight(); + } + } + else if (_stage == 2) + { + Triple stage3 = doStageThree(); + + if (stage3.getLeft()) + { + return; + } + + stageTitle = stage3.getMiddle(); + if (stage3.getRight() != null) + { + stageMaterial = stage3.getRight(); + } + } + else if (_stage == 3) + { + Pair stage4 = doStageFour(); + + stageTitle = stage4.getLeft(); + if (stage4.getRight() != null) + { + stageMaterial = stage4.getRight(); + } + } + else if (_stage == 4) + { + Pair stage5 = doStageFive(); + + stageTitle = stage5.getLeft(); + if (stage5.getRight() != null) + { + stageMaterial = stage5.getRight(); + } + } + else + { + finish(); + stageTitle = "The End"; + } + } + catch (InstantiationException | IllegalAccessException e) + { + e.printStackTrace(); + } + + addButton(4, stageMaterial, 0, stageTitle, (player, clickType) -> {}, false); + + addButton(45, Material.REDSTONE_BLOCK, 0, C.cRed + "Previous page", _backButton, false); + addButton(53, Material.EMERALD_BLOCK, 0, C.cGreen + "Next page", _nextButton, false); + } + + private Pair doStageOne() + { + String stageTitle; + + int[] indices = UtilUI.getIndicesFor(5, 1, 1); + + stageTitle = "1. Select Item Type"; + addButton(indices[0], Material.GOLD_RECORD, 0, C.cGold + "Legendary", new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory = RareItemFactory.begin(ItemType.LEGENDARY); + performNext(); + buildPage(); + } + }, _factory != null && ItemType.LEGENDARY.equals(_factory.getItemType()), new String[] { _factory != null && ItemType.LEGENDARY.equals(_factory.getItemType()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + addButton(indices[1], Material.RECORD_7, 0, C.cAqua + "Rare", new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory = RareItemFactory.begin(ItemType.RARE); + performNext(); + buildPage(); + } + }, _factory != null && ItemType.RARE.equals(_factory.getItemType()), new String[] { _factory != null && ItemType.RARE.equals(_factory.getItemType()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + addButton(indices[2], Material.DIAMOND_SWORD, 0, C.cDGreen + "Weapon", new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory = RareItemFactory.begin(ItemType.WEAPON); + performNext(); + buildPage(); + } + }, _factory != null && ItemType.RARE.equals(_factory.getItemType()), new String[] { _factory != null && ItemType.RARE.equals(_factory.getItemType()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + addButton(indices[3], Material.DIAMOND_CHESTPLATE, 0, C.cDGreen + "Armor", new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory = RareItemFactory.begin(ItemType.ARMOR); + performNext(); + buildPage(); + } + }, _factory != null && ItemType.ARMOR.equals(_factory.getItemType()), new String[] { _factory != null && ItemType.ARMOR.equals(_factory.getItemType()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + addButton(indices[4], Material.BOW, 0, C.cDGreen + "Bow", new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory = RareItemFactory.begin(ItemType.BOW); + performNext(); + buildPage(); + } + }, _factory != null && ItemType.BOW.equals(_factory.getItemType()), new String[] { _factory != null && ItemType.BOW.equals(_factory.getItemType()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + return Pair.create(stageTitle, null); + } + + private Triple doStageTwo() throws InstantiationException, IllegalAccessException + { + String stageTitle = "Fatal Error"; + Material stageMaterial = null; + boolean $return = false; + + if (_factory == null || _factory.getItemType() == null) + { + performBack(); + return Triple.of(true, stageTitle, stageMaterial); + } + + if (_factory.getItemType().equals(ItemType.RARE)) + { + stageTitle = "2. Select Rare Item"; + stageMaterial = _factory.getMaterial() == null ? stageMaterial : _factory.getMaterial(); + + int[] indices = UtilUI.getIndicesFor(_rareItems.size(), 1); + + int index = 0; + for (final Class rare : _rareItems) + { + final RareItem item = rare.newInstance(); + + List lore = new ArrayList<>(); + + lore.addAll(UtilCollections.toList(item.getDescription())); + + lore.add(" "); + lore.add(item.getDisplayName().equals(_factory.getWrapper() == null ? null : _factory.getWrapper().getDisplayName()) ? C.cGreen + "Selected" : C.cRed + "Not Selected"); + + addButton(indices[index], item.toItemStack().getType(), 0, C.cAqua + item.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory.setRare(rare); + performNext(); + buildPage(); + } + }, item.getDisplayName().equals(_factory.getWrapper() == null ? null : _factory.getWrapper().getDisplayName()), lore.toArray(new String[lore.size()])); + + index++; + } + } + else if (_factory.getItemType().equals(ItemType.LEGENDARY)) + { + stageTitle = "2. Select Legendary Item"; + stageMaterial = _factory.getMaterial() == null ? stageMaterial : _factory.getMaterial(); + + int[] indices = UtilUI.getIndicesFor(_legendaryItems.size(), 1); + + int index = 0; + for (final Class legendary : _legendaryItems) + { + final LegendaryItem item = legendary.newInstance(); + + List lore = new ArrayList<>(); + + lore.addAll(Arrays.asList(item.getDescription())); + + lore.add(" "); + lore.add(item.getDisplayName().equals(_factory.getWrapper() == null ? null : _factory.getWrapper().getDisplayName()) ? C.cGreen + "Selected" : C.cRed + "Not Selected"); + + addButton(indices[index], item.toItemStack().getType(), 0, C.cGold + item.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory.setLegendary(legendary); + performNext(); + buildPage(); + } + }, item.getDisplayName().equals(_factory.getWrapper() == null ? null : _factory.getWrapper().getDisplayName()), lore.toArray(new String[lore.size()])); + + index++; + } + } + else + { + switch (_factory.getItemType()) + { + case WEAPON: + { + stageTitle = "Select Weapon Type"; + + int[] indices = UtilUI.getIndicesFor(_weaponTypes.size(), 1); + + int index = 0; + for (final Material type : _weaponTypes) + { + addButton(indices[index], type, 0, C.cGold + WordUtils.capitalizeFully(type.toString()), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory.setType(type); + performNext(); + buildPage(); + } + }, type.equals(_factory.getMaterial()), new String[] { type.equals(_factory.getMaterial()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + index++; + } + break; + } + case ARMOR: + { + stageTitle = "Select Armor Type"; + + int[] indices = UtilUI.getIndicesFor(_armorTypes.size(), 1, 4, 0); + + int index = 0; + for (final Material type : _armorTypes) + { + addButton(indices[index], type, 0, C.cGold + WordUtils.capitalizeFully(type.toString()), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _factory.setType(type); + performNext(); + buildPage(); + } + }, type.equals(_factory.getMaterial()), new String[] { type.equals(_factory.getMaterial()) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + index++; + } + break; + } + default: + { + if (_factory.getMaterial() != null) + { + performBack(); + performBack(); + break; + } + + /** + * The only time this code block should be reached is when + * _itemType is BOW, or if there are ever new item types + * added which don't have a case, since LEGENDARY is checked + * separately, and ARMOR, and WEAPON have their own cases. + */ + + _factory.setType(Material.BOW); + _stage = 2; + buildPage(); + $return = true; + + break; + } + } + } + return Triple.of($return, stageTitle, stageMaterial); + } + + private Triple doStageThree() throws InstantiationException, IllegalAccessException + { + String stageTitle; + + if (_factory.getMaterial() == null) + { + performBack(); + return Triple.of(true, null, null); + } + + Material stageMaterial = _factory.getMaterial(); + + if (_factory.getItemType().equals(ItemType.LEGENDARY) || _factory.getItemType().equals(ItemType.RARE)) + { + finish(); + stageTitle = "The End"; + } + else + { + switch (_factory.getItemType()) + { + case WEAPON: + { + stageTitle = "Select Super Prefix"; + + int[] indices = UtilUI.getIndicesFor(_weaponSuperPrefixes.size(), 1); + + int index = 0; + for (final Class attribute : _weaponSuperPrefixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], stageMaterial, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _superPrefix = (attribute.equals(_superPrefix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_superPrefix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_superPrefix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + case ARMOR: + { + stageTitle = "Select Super Prefix"; + int[] indices = UtilUI.getIndicesFor(_armorSuperPrefixes.size(), 1); + + int index = 0; + for (final Class attribute : _armorSuperPrefixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], stageMaterial, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _superPrefix = (attribute.equals(_superPrefix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_superPrefix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_superPrefix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + case BOW: + { + stageTitle = "Select Super Prefix"; + + int[] indices = UtilUI.getIndicesFor(_bowSuperPrefixes.size(), 1); + + int index = 0; + for (final Class attribute : _bowSuperPrefixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], Material.BOW, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _superPrefix = (attribute.equals(_superPrefix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_superPrefix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_superPrefix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + default: + { + stageTitle = "Fatal Error"; + stageMaterial = Material.REDSTONE_BLOCK; + } + } + } + + return Triple.of(false, stageTitle, stageMaterial); + } + + private Pair doStageFour() throws InstantiationException, IllegalAccessException + { + String stageTitle; + Material stageMaterial = _factory.getMaterial(); + + if (_factory.getItemType().equals(ItemType.LEGENDARY)) + { + finish(); + stageTitle = "The End"; + } + else + { + switch (_factory.getItemType()) + { + case WEAPON: + { + stageTitle = "Select Prefix"; + + int[] indices = UtilUI.getIndicesFor(_weaponPrefixes.size(), 1); + + int index = 0; + for (final Class attribute : _weaponPrefixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], stageMaterial, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _prefix = (attribute.equals(_prefix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_prefix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_prefix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + case ARMOR: + { + stageTitle = "Select Prefix"; + + int[] indices = UtilUI.getIndicesFor(_armorPrefixes.size(), 1); + + int index = 0; + for (final Class attribute : _armorPrefixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], stageMaterial, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _prefix = (attribute.equals(_prefix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_prefix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_prefix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + case BOW: + { + stageTitle = "Select Prefix"; + + int[] indices = UtilUI.getIndicesFor(_bowPrefixes.size(), 1); + + int index = 0; + for (final Class attribute : _bowPrefixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], Material.BOW, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _prefix = (attribute.equals(_prefix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_prefix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_prefix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + default: + { + stageTitle = "Fatal Error"; + stageMaterial = Material.REDSTONE_BLOCK; + } + } + } + + return Pair.create(stageTitle, stageMaterial); + } + + private Pair doStageFive() throws InstantiationException, IllegalAccessException + { + String stageTitle; + Material stageMaterial = _factory.getMaterial(); + + if (_factory.getItemType().equals(ItemType.LEGENDARY)) + { + finish(); + stageTitle = "The End"; + } + else + { + switch (_factory.getItemType()) + { + case WEAPON: + { + stageTitle = "Select Suffix"; + + int[] indices = UtilUI.getIndicesFor(_weaponSuffixes.size(), 1); + + int index = 0; + for (final Class attribute : _weaponSuffixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], stageMaterial, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _suffix = (attribute.equals(_suffix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_suffix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_suffix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + case ARMOR: + { + stageTitle = "Select Suffix"; + + int[] indices = UtilUI.getIndicesFor(_armorSuffixes.size(), 1); + + int index = 0; + for (final Class attribute : _armorSuffixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], stageMaterial, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _suffix = (attribute.equals(_suffix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_suffix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_suffix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + index++; + } + break; + } + case BOW: + { + stageTitle = "Select Suffix"; + + int[] indices = UtilUI.getIndicesFor(_bowSuffixes.size(), 1); + + int index = 0; + for (final Class attribute : _bowSuffixes) + { + final ItemAttribute attrib = attribute.newInstance(); + + addButton(indices[index], Material.BOW, 0, C.cGold + attrib.getDisplayName(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + _suffix = (attribute.equals(_suffix) ? null : attribute); + performNext(); + buildPage(); + } + }, attribute.equals(_suffix), new String[] { C.cWhite + attrib.getDescription(), "", attribute.equals(_suffix) ? C.cGreen + "Selected" : C.cRed + "Not Selected" }); + + index++; + } + break; + } + default: + { + stageTitle = "Fatal Error"; + stageMaterial = Material.REDSTONE_BLOCK; + } + } + } + + return Pair.create(stageTitle, stageMaterial); + } + + private void addButton(final int index, final Material type, final int data, final String name, final IButton ibutton, final boolean dullEnchantment, final String... description) + { + ShopItem shopItem; + + if (dullEnchantment) + { + shopItem = new ShopItem(type, (byte) data, name, description, 1, ibutton == null, false).addGlow(); + } + else + { + shopItem = new ShopItem(type, (byte) data, name, description, 1, ibutton == null, false); + } + + addButton(index, shopItem, ibutton); + } + + private void addButton(final int index, final ItemStack stack, final IButton ibutton, final String... description) + { + addButton(index, new ShopItem(stack, ibutton == null, false), ibutton); + } + + private void performBack() + { + if (_stage > 0) + { + _stage--; + buildPage(); + } + } + + protected void finish() + { + clearPage(); + + _factory.setSuperPrefix(_superPrefix); + _factory.setPrefix(_prefix); + _factory.setSuffix(_suffix); + + final ItemStack item = _factory.fabricate(); + + addButton(9 + 4, item, new IButton() + { + public void onClick(Player player, ClickType clickType) + { + player.getInventory().addItem(item); + getPlugin().getPlayerGear(player).updateCache(true); + } + }, new String[] { C.cWhite + "Click to get item" }); + } + + protected void performNext() + { + if (_stage <= 4) + { + _stage++; + } + buildPage(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearShop.java new file mode 100644 index 00000000..1454b71a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/items/ui/GearShop.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.items.ui; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.items.GearManager; + +public class GearShop extends ShopBase +{ + public GearShop(final GearManager plugin, final CoreClientManager clientManager, final DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Customize New Gear"); + } + + @Override + protected ShopPageBase> buildPagesFor(final Player player) + { + return new GearPage(getPlugin(), this, getClientManager(), getDonationManager(), "Customize New Gear", player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/message/ClansMessageManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/message/ClansMessageManager.java new file mode 100644 index 00000000..ac9a0332 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/message/ClansMessageManager.java @@ -0,0 +1,65 @@ +package mineplex.game.clans.message; + +import java.util.HashMap; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class ClansMessageManager extends MiniPlugin +{ + private static final Message BLANK_MESSAGE = new Message("", "", 20); + + private HashMap _playerMessageMap; + + public ClansMessageManager(JavaPlugin plugin) + { + super("Message", plugin); + + _playerMessageMap = new HashMap<>(); + } + + @EventHandler + public void tick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + _playerMessageMap.forEach((player, message) ->{ + message.increment(); + if (message.shouldSend()) + { + message.send(player); + } + }); + } + + public void setMessage(Player player, String title, String description, int ticksBetween, boolean displayNow) + { + Message message = new Message(title, description, ticksBetween); + _playerMessageMap.put(player, message); + if (displayNow) message.send(player); + } + + public void removePlayer(Player player) + { + removePlayer(player, true); + } + + public void removePlayer(Player player, boolean sendBlankMessage) + { + BLANK_MESSAGE.send(player); + _playerMessageMap.remove(player); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + removePlayer(event.getPlayer(), false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/message/Message.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/message/Message.java new file mode 100644 index 00000000..56910d73 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/message/Message.java @@ -0,0 +1,47 @@ +package mineplex.game.clans.message; + +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilTextMiddle; + +public class Message +{ + private int _ticksBetweenMessage; + private int _ticks; + + private String _title; + private String _description; + + public Message(String title, String description, int ticksBetweenMessage) + { + _title = title; + _description = description; + _ticksBetweenMessage = ticksBetweenMessage; + _ticks = 0; + } + + protected void send(Player player) + { + UtilTextMiddle.display(_title, _description, player); + } + + public int getTicks() + { + return _ticks; + } + + public int getTicksBetweenMessage() + { + return _ticksBetweenMessage; + } + + public void increment() + { + _ticks++; + } + + public boolean shouldSend() + { + return _ticks % _ticksBetweenMessage == 0; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/restart/RestartCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/restart/RestartCommand.java new file mode 100644 index 00000000..d2e16e27 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/restart/RestartCommand.java @@ -0,0 +1,32 @@ +package mineplex.game.clans.restart; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; + +public class RestartCommand extends CommandBase +{ + public RestartCommand(RestartManager plugin) + { + super(plugin, RestartManager.Perm.RESTART_COMMAND, "forceRestart"); + } + + @Override + public void Execute(Player caller, String[] args) + { + UtilPlayer.message(caller, F.main("Clans", "Initiating server restart!")); + Plugin.restart(); + if (!UtilServer.isTestServer()) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-commandspy", + new SlackMessage("Clans Command Logger", "crossed_swords", caller.getName() + " has initiated a restart of " + UtilServer.getServerName() + "."), + true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/restart/RestartManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/restart/RestartManager.java new file mode 100644 index 00000000..41724f39 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/restart/RestartManager.java @@ -0,0 +1,306 @@ +package mineplex.game.clans.restart; + +import java.util.Calendar; +import java.util.LinkedList; + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.event.server.ServerCommandEvent; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import com.mineplex.clansqueue.common.ClansQueueMessenger; +import com.mineplex.clansqueue.common.QueueConstant; +import com.mineplex.clansqueue.common.messages.ServerOfflineMessage; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +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.common.util.UtilTime.TimeUnit; +import mineplex.core.portal.GenericServer; +import mineplex.core.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.RestartServerEvent; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.supplydrop.SupplyDropManager; +import mineplex.game.clans.gameplay.safelog.npc.NPCManager; +import net.minecraft.server.v1_8_R3.MinecraftServer; + +public class RestartManager extends MiniPlugin +{ + public enum Perm implements Permission + { + RESTART_COMMAND, + } + + private static final int MAX_RESTART_TIME = 2; //Server won't auto restart after 2am + private final LinkedList _warnings = new LinkedList<>(); + private Long _restartUnlock; + private Long _restartTime = -1L; + private boolean _restarting; + + private final String _serverName; + private final boolean _testServer; + + public RestartManager(JavaPlugin plugin) + { + super("Restart Manager", plugin); + + _serverName = plugin.getConfig().getString("serverstatus.name"); + _testServer = UtilServer.isTestServer(); + + int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); + if (inRestartZone(hour)) + { + _restartUnlock = System.currentTimeMillis() + 1000 + UtilTime.convert(MAX_RESTART_TIME - hour, TimeUnit.HOURS, TimeUnit.MILLISECONDS); + } + else + { + _restartUnlock = System.currentTimeMillis(); + } + + _warnings.add(60000L); + _warnings.add(30000L); + _warnings.add(10000L); + _warnings.add(5000L); + addCommand(new RestartCommand(this)); + + if (!_testServer) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-server-status", new SlackMessage("Clans Uptime", "crossed_swords", _serverName + " has started up!"), true); + } + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.CMOD.setPermission(Perm.RESTART_COMMAND, false, true); + PermissionGroup.QAM.setPermission(Perm.RESTART_COMMAND, false, true); + PermissionGroup.ADMIN.setPermission(Perm.RESTART_COMMAND, true, true); + } + + private boolean inRestartZone(int hour) + { + return hour >= 0 && hour < MAX_RESTART_TIME; //12 am = 0 + } + + private boolean tryRestartTime() + { + if (!inRestartZone(Calendar.getInstance().get(Calendar.HOUR_OF_DAY)) || System.currentTimeMillis() < _restartUnlock) + { + return false; + } + if (ClansManager.getInstance().getAmplifierManager().hasActiveAmplifier()) + { + return false; + } + if (ClansManager.getInstance().getNetherManager().InNether.size() > 0) + { + return false; + } + if (ClansManager.getInstance().getWorldEvent().getEvents().size() > 0) + { + return false; + } + if (ClansManager.getInstance().getWorldEvent().getRaidManager().getActiveRaids() > 0) + { + return false; + } + if (Managers.get(SupplyDropManager.class).hasActiveSupplyDrop()) + { + return false; + } + + return true; + } + + private boolean tryRestartTps() + { + boolean restart = MinecraftServer.getServer().recentTps[0] <= 12; + + if (restart && !_testServer) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-server-status", new SlackMessage("Clans Uptime", "crossed_swords", _serverName + " has scheduled an immediate restart due to low TPS!"), true); + } + + return restart; + } + + public boolean isRestarting() + { + return _restarting; + } + + @Override + public void disable() + { + if (!_testServer) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-server-status", new SlackMessage("Clans Uptime", "crossed_swords", _serverName + " has shut down!"), true); + } + } + + public void restart() + { + ServerOfflineMessage message = new ServerOfflineMessage(); + message.ServerName = UtilServer.getServerName(); + ClansQueueMessenger.getMessenger(UtilServer.getServerName()).transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + Bukkit.broadcastMessage(F.main("Clans", "This Clans server will be restarting in " + F.elem(UtilTime.MakeStr(120000)) + "!")); + UtilTextMiddle.display(C.cRed + "Server Restart", C.cGray + "This server will restart in " + F.elem(UtilTime.MakeStr(120000)) + "!"); + _restartTime = System.currentTimeMillis() + 120000; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void reflectMotd(ServerListPingEvent event) + { + if (_restarting) + { + event.setMotd("Restarting soon"); + } + } + + @EventHandler + public void blockLogin(PlayerLoginEvent event) + { + if (_restarting) + { + event.disallow(Result.KICK_OTHER, C.cRed + "This server is restarting!"); + } + } + + @EventHandler + public void onRestart(RestartServerEvent event) + { + event.setCancelled(true); + + if (_restarting || _restartTime != -1) + { + return; + } + + restart(); + } + + @EventHandler + public void onShutdownCommand(ServerCommandEvent event) + { + String command = event.getCommand().toLowerCase().trim(); + if (command.equals("stop") || command.startsWith("stop ")) + { + if (UtilServer.isTestServer() && command.endsWith(" -f")) + { + return; + } + + event.setCancelled(true); + + if (_restarting || _restartTime != -1) + { + return; + } + + restart(); + } + } + + @EventHandler + public void onShutdownCommand(PlayerCommandPreprocessEvent event) + { + String command = event.getMessage().toLowerCase().trim(); + if (command.startsWith("/") && command.length() > 1) + { + command = command.substring(1); + } + else + { + return; + } + + if (!command.equals("stop") && !command.startsWith("stop ")) + { + return; + } + + if (!event.getPlayer().isOp() && !event.getPlayer().hasPermission("bukkit.command.stop")) + { + return; + } + + if (UtilServer.isTestServer() && command.endsWith(" -f")) + { + return; + } + + event.setCancelled(true); + + if (_restarting || _restartTime != -1) + { + return; + } + + restart(); + } + + @EventHandler + public void checkRestart(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + if (_restarting) + { + return; + } + + if (_restartTime != -1) + { + if (!_warnings.isEmpty()) + { + if (_restartTime - System.currentTimeMillis() <= _warnings.getFirst()) + { + Long time = _warnings.removeFirst(); + Bukkit.broadcastMessage(F.main("Clans", "This Clans server will be restarting in " + F.elem(UtilTime.MakeStr(time)) + "!")); + } + } + if (System.currentTimeMillis() >= _restartTime) + { + _restarting = true; + NPCManager.getInstance().disable(); + Portal.getInstance().sendAllPlayersToGenericServer(GenericServer.CLANS_HUB, Intent.KICK); + runSyncLater(() -> + { + if (!_testServer) + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#clans-server-status", new SlackMessage("Clans Uptime", "crossed_swords", _serverName + " is now restarting!"), true); + } + Bukkit.shutdown(); + }, 120L); + } + } + else + { + if (tryRestartTime() || tryRestartTps()) + { + restart(); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ClansShopItem.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ClansShopItem.java new file mode 100644 index 00000000..a373d6b2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ClansShopItem.java @@ -0,0 +1,201 @@ +package mineplex.game.clans.shop; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.C; + +public enum ClansShopItem +{ + // PvP Shop + GOLD_HELMET(2500, 500, Material.GOLD_HELMET, 1), + GOLD_CHESTPLATE(4000, 800, Material.GOLD_CHESTPLATE, 1), + GOLD_LEGGINGS(3500, 700, Material.GOLD_LEGGINGS, 1), + GOLD_BOOTS(2000, 400, Material.GOLD_BOOTS, 1), + LEATHER_HELMET(2500, 500, Material.LEATHER_HELMET, 1), + LEATHER_CHESTPLATE(4000, 800, Material.LEATHER_CHESTPLATE, 1), + LEATHER_LEGGINGS(3500, 700, Material.LEATHER_LEGGINGS, 1), + LEATHER_BOOTS(2000, 400, Material.LEATHER_BOOTS, 1), + CHAINMAIL_HELMET(2500, 500, Material.CHAINMAIL_HELMET, 1), + CHAINMAIL_CHESTPLATE(4000, 800, Material.CHAINMAIL_CHESTPLATE, 1), + CHAINMAIL_LEGGINGS(3500, 700, Material.CHAINMAIL_LEGGINGS, 1), + CHAINMAIL_BOOTS(2000, 500, Material.CHAINMAIL_BOOTS, 1), + IRON_HELMET(2500, 500, Material.IRON_HELMET, 1), + IRON_CHESTPLATE(4000, 800, Material.IRON_CHESTPLATE, 1), + IRON_LEGGINGS(3500, 700, Material.IRON_LEGGINGS, 1), + IRON_BOOTS(2000, 400, Material.IRON_BOOTS, 1), + DIAMOND_HELMET(2500, 500, Material.DIAMOND_HELMET, 1), + DIAMOND_CHESTPLATE(4000, 800, Material.DIAMOND_CHESTPLATE, 1), + DIAMOND_LEGGINGS(3500, 700, Material.DIAMOND_LEGGINGS, 1), + DIAMOND_BOOTS(2000, 400, Material.DIAMOND_BOOTS, 1), + IRON_SWORD(1000, 200, Material.IRON_SWORD, 1), + DIAMOND_SWORD(9000, 1800, Material.DIAMOND_SWORD, 1), + GOLD_SWORD(9000, 1800, Material.GOLD_SWORD, 1), + IRON_AXE(1500, 300, Material.IRON_AXE, 1), + DIAMOND_AXE(13500, 2700, Material.DIAMOND_AXE, 1), + GOLD_AXE(13500, 2700, Material.GOLD_AXE, 1), + BOW(175, 35, Material.BOW, 1), + ARROW(10, 2, Material.ARROW, 1), + ENCHANTMENT_TABLE(30000, 0, Material.ENCHANTMENT_TABLE, 1), + TNT(20000, 0, Material.TNT, 1), + TNT_GENERATOR(300000, 0, Material.BREWING_STAND_ITEM, 1), + // Mining Shop + IRON_INGOT(500, 100, Material.IRON_INGOT, 1), + GOLD_INGOT(500, 100, Material.GOLD_INGOT, 1), + DIAMOND(500, 100, Material.DIAMOND, 1), + LEATHER(500, 100, Material.LEATHER, 1), + COAL(50, 10, Material.COAL, 1), + REDSTONE(10, 2, Material.REDSTONE, 1), + LAPIS_BLOCK(500, 100, Material.LAPIS_BLOCK, 1), + // Farming Shop + POTATO_ITEM(15, 8, Material.POTATO_ITEM, 1), + MELON(5, 3, Material.MELON, 1), + BREAD(30, 16, Material.BREAD, 1), + COOKED_BEEF(50, 27, Material.COOKED_BEEF, 1), + GRILLED_PORK(50, 27, Material.GRILLED_PORK, 1), + COOKED_CHICKEN(35, 19, Material.COOKED_CHICKEN, 1), + FEATHER(50, 10, Material.FEATHER, 1), + CARROT_ITEM(10, 5, Material.CARROT_ITEM, 1), + MUSHROOM_SOUP(200, 109, Material.MUSHROOM_SOUP, 1), + SUGAR_CANE(15, 3, Material.SUGAR_CANE, 1), + PUMPKIN(30, 6, Material.PUMPKIN, 1), + STRING(50, 10, Material.STRING, 1), + BONE(1, 1, Material.BONE, 1), + ROTTEN_FLESH(5, 5, Material.ROTTEN_FLESH, 1), + SPIDER_EYE(5, 5, Material.SPIDER_EYE, 1), + // Building Shop + STONE(100, 20, Material.STONE, 1), + SMOOTH_BRICK(100, 20, Material.SMOOTH_BRICK, 1), + CRACKED_STONE_BRICK(25, 5, Material.SMOOTH_BRICK, 1, (byte) 2), + COBBLESTONE(100, 20, Material.COBBLESTONE, 1), + LOG(50, 10, Material.LOG, 1), + LOG_2(50, 10, Material.LOG_2, 1), + SAND(20, 4, Material.SAND, 1), + GLASS(30, 6, Material.GLASS, 1), + SANDSTONE(80, 16, Material.SANDSTONE, 1), + DIRT(10, 2, Material.DIRT, 1), + NETHER_BRICK(50, 10, Material.NETHER_BRICK, 1), + QUARTZ_BLOCK(75, 15, Material.QUARTZ_BLOCK, 1), + CLAY(30, 6, Material.CLAY, 1), + GOLD_TOKEN(50000, 50000, Material.GOLD_RECORD, 1, (byte) 0, "Gold Token"), + OUTPOST(100000, 0, Material.BEACON, 1, (byte) 0, C.cBlue + "Outpost"), + CANNON(25000, 0, Material.SPONGE, 1, (byte) 1, C.cBlue + "Cannon"); + + private int _buyPrice; + private int _sellPrice; + private int _amount; + private short _data; + + private String _displayName; + + private Material _material; + + ClansShopItem(int buyPrice, int sellPrice, Material material, int amount, short data) + { + _buyPrice = buyPrice; + _sellPrice = sellPrice; + _material = material; + _amount = amount; + _data = data; + } + + ClansShopItem(int buyPrice, int sellPrice, Material material, int amount) + { + this(buyPrice, sellPrice, material, amount, (byte) 0); + } + + ClansShopItem(int buyPrice, int sellPrice, Material material, int amount, byte data, String name) + { + this(buyPrice, sellPrice, material, amount, data); + _displayName = name; + } + + public int getBuyPrice() + { + return _buyPrice; + } + + public int getSellPrice() + { + return _sellPrice; + } + + public short getData() + { + return _data; + } + + public String getDisplayName() + { + return _displayName; + } + + public int getBuyPrice(int amount) + { + return _amount == 1 ? _buyPrice * amount : ((int) (((int) ((double) _buyPrice) / ((double) _amount))) * amount); + } + + public int getSellPrice(int amount) + { + return _amount == 1 ? _sellPrice * amount : ((int) (((int) ((double) _sellPrice) / ((double) _amount))) * amount); + } + + public int getAmount() + { + return _amount; + } + + public Material getMaterial() + { + return _material; + } + + public static ClansShopItem getByMaterial(Material material) + { + for (ClansShopItem item : values()) + { + if (item.getMaterial().equals(material)) + { + return item; + } + } + + return null; + } + + public static ClansShopItem getByItem(Material material, short data) + { + for (ClansShopItem item : values()) + { + if (item.getMaterial().equals(material) && (item.getData() == -1 || item.getData() == data)) + { + return item; + } + } + + return null; + } + + public static ClansShopItem getByItem(ItemStack stack, boolean checkData, boolean checkDisplayName) + { + for (ClansShopItem item : values()) + { + if (item.getMaterial().equals(stack.getType())) + { + if (checkData && stack.getDurability() != item.getData()) + { + continue; + } + + if (checkDisplayName && stack.hasItemMeta() && stack.getItemMeta().hasDisplayName() && !stack.getItemMeta().getDisplayName().equals(item.getDisplayName())) + { + continue; + } + + return item; + } + } + + return null; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ClansShopPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ClansShopPage.java new file mode 100644 index 00000000..f32673b0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ClansShopPage.java @@ -0,0 +1,106 @@ +package mineplex.game.clans.shop; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilServer; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansShopAddButtonEvent; + +public abstract class ClansShopPage> extends ShopPageBase +{ + + /** + * Constructor + * + * @param plugin + * @param shop + * @param clientManager + * @param donationManager + * @param name + * @param player + * @param slots + */ + public ClansShopPage(ClansManager plugin, T shop, CoreClientManager clientManager, DonationManager donationManager, String name, Player player, int slots) + { + super(plugin, shop, clientManager, donationManager, name, player, slots); + } + + /** + * Constructor + * + * @param plugin + * @param shop + * @param clientManager + * @param donationManager + * @param name + * @param player + */ + public ClansShopPage(ClansManager plugin, T shop, CoreClientManager clientManager, DonationManager donationManager, String name, Player player) + { + super(plugin, shop, clientManager, donationManager, name, player); + } + + public void addShopItem(int slot, Material material, int buyPrice, int sellPrice) + { + addShopItem(slot, material, buyPrice, sellPrice, Clans.prettifyName(material)); + } + + public void addShopItem(int slot, Material material, int buyPrice, int sellPrice, byte data) + { + addShopItem(slot, material, buyPrice, sellPrice, data, Clans.prettifyName(material), 1); + } + + public void addShopItem(int slot, Material material, int buyPrice, int sellPrice, String displayName) + { + addShopItem(slot, material, buyPrice, sellPrice, (byte) 0, displayName, 1); + } + + public void addShopItem(int slot, Material material, int buyPrice, int sellPrice, byte data, String displayName, int amount) + { + ClansShopAddButtonEvent event = new ClansShopAddButtonEvent(getPlayer(), getShop(), slot, material, buyPrice, sellPrice, data, displayName, amount); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) return; + + slot = event.getSlot(); + material = event.getMaterial(); + buyPrice = event.getBuyPrice(); + sellPrice = event.getSellPrice(); + data = event.getData(); + displayName = event.getDisplayName(); + amount = event.getAmount(); + + if (!event.isCancelled()) + { + PvpItem item = new PvpItem(material, data, 1, displayName, buyPrice, sellPrice, 64); + addButton(slot, item, new ShopItemButton>(this, buyPrice, sellPrice, material, data, amount, displayName)); + } + } + + public void addShopItem(int index, ClansShopItem item, String displayName) + { + addShopItem(index, item, (byte) item.getData(), displayName, 1); + } + + public void addShopItem(int index, ClansShopItem item) + { + addShopItem(index, item, (byte) item.getData()); + } + + public void addShopItem(int index, ClansShopItem item, byte data) + { + addShopItem(index, item.getMaterial(), item.getBuyPrice(), item.getSellPrice(), data); + } + + public void addShopItem(int index, ClansShopItem item, byte data, String displayName, int amount) + { + addShopItem(index, item.getMaterial(), item.getBuyPrice(), item.getSellPrice(), data, displayName, amount); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/PvpItem.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/PvpItem.java new file mode 100644 index 00000000..c87a00d3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/PvpItem.java @@ -0,0 +1,69 @@ +package mineplex.game.clans.shop; + +import org.bukkit.Material; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilItem; +import mineplex.core.shop.item.ShopItem; + +public class PvpItem extends ShopItem +{ + private static String LEFT_CLICK_BUY = C.cYellow + "Left-Click" + C.cWhite + " to Buy " + C.cGreen + 1; + private static String RIGHT_CLICK_SELL = C.cYellow + "Right-Click" + C.cWhite + " to Sell " + C.cGreen + 1; + + private int _price; + private int _sellPrice; + private int _bulkCount; + + public PvpItem(Material type, byte data, int displayAmount, String name, int price, int bulkCount) + { + super(type, data, name, new String[] { C.cWhite + " ", LEFT_CLICK_BUY, C.cWhite + "Costs " + C.cGreen + price + "g", C.cWhite + " ", C.cYellow + "Shift Left-Click" + C.cWhite + " to Buy " + C.cGreen + bulkCount, C.cWhite + "Costs " + C.cGreen + (price * bulkCount) + "g", C.cWhite + " ", RIGHT_CLICK_SELL, C.cWhite + "Earns " + C.cGreen + (int) (price / 2) + "g", C.cWhite + " ", C.cYellow + "Shift Right-Click" + C.cWhite + " to Sell " + C.cGreen + "All", }, 0, false, false); + + _price = price; + _sellPrice = (int) (price / 2); + _bulkCount = bulkCount; + } + + public PvpItem(Material type, byte data, int displayAmount, String name, int buyPrice, int sellPrice, int bulkCount) + { + super(type, data, name, new String[] { + C.cWhite + " ", + LEFT_CLICK_BUY, + C.cWhite + "Costs " + C.cGreen + (buyPrice == 0 ? "Free (Tutorial)" : buyPrice + "g"), + C.cWhite + " ", + UtilItem.isArmor(type) || UtilItem.isTool(type) || type == Material.BOW ? "" : C.cYellow + "Shift Left-Click" + C.cWhite + " to Buy " + C.cGreen + bulkCount, + UtilItem.isArmor(type) || UtilItem.isTool(type) || type == Material.BOW ? "" : C.cWhite + "Costs " + C.cGreen + (buyPrice * bulkCount) + "g", C.cWhite + " ", + RIGHT_CLICK_SELL, + C.cWhite + "Earns " + C.cGreen + (sellPrice == 0 ? "Free" : sellPrice + ""), + C.cWhite + " ", + C.cYellow + "Shift Right-Click" + C.cWhite + " to Sell " + C.cGreen + "All", + }, 0, false, false); + + _price = buyPrice; + _sellPrice = sellPrice; + _bulkCount = bulkCount; + } + + public PvpItem(Material type, byte data, int displayAmount, String name, int price) + { + super(type, data, name, new String[] { C.cWhite + " ", LEFT_CLICK_BUY, C.cWhite + "Costs " + C.cGreen + price + "g", C.cWhite + " ", RIGHT_CLICK_SELL, C.cWhite + "Earns " + C.cGreen + (int) (price / 2) + "g", C.cWhite + " ", C.cYellow + "Shift Right-Click" + C.cWhite + " to Sell " + C.cGreen + "All", }, 0, false, false); + + _price = price; + _bulkCount = -1; + } + + public int getPrice() + { + return _price; + } + + public int getSellPrice() + { + return _sellPrice; + } + + public int getBulkCount() + { + return _bulkCount; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ShopItemButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ShopItemButton.java new file mode 100644 index 00000000..a4987b30 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/ShopItemButton.java @@ -0,0 +1,182 @@ +package mineplex.game.clans.shop; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.InventoryUtil; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.event.ClansPlayerBuyItemEvent; +import mineplex.game.clans.clans.event.ClansPlayerSellItemEvent; +import mineplex.game.clans.economy.GoldManager; + +public class ShopItemButton> implements IButton +{ + private int _buyPrice; + private int _sellPrice; + private ItemStack _item; + private T _page; + + public ShopItemButton(T page, int buyPrice, int sellPrice, Material material, byte data, int amount, String displayName) + { + _page = page; + _sellPrice = sellPrice; + _buyPrice = buyPrice; + _item = new ItemStack(material, amount, data); + + if (displayName != null) + { + ItemMeta meta = _item.getItemMeta(); + if (meta == null) + { + meta = Bukkit.getItemFactory().getItemMeta(material); + } + + meta.setDisplayName(C.Reset + displayName); + + _item.setItemMeta(meta); + } + } + + public ShopItemButton(T page, int buyPrice, int sellPrice, Material material) + { + this(page, buyPrice, sellPrice, material, (byte) 0, 1, null); + } + + @Override + public void onClick(final Player player, ClickType clickType) + { + boolean shiftClick = (clickType == ClickType.SHIFT_LEFT || clickType == ClickType.SHIFT_RIGHT); + + if (clickType == ClickType.SHIFT_RIGHT || clickType == ClickType.RIGHT) + { + int amount = 1; // # of items removed/sold from inventory + + if (!hasItem(player, _item)) + { + _page.playDenySound(player); + notify(player, "You do not have any of the appropriate item in your inventory."); + return; + } + + ClansPlayerSellItemEvent event = new ClansPlayerSellItemEvent(player, _page, ShopItemButton.this, _item, getAmount(player, _item) * _sellPrice, getAmount(player, _item)); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return; + } + + if (shiftClick) + { + amount = InventoryUtil.getCountOfObjectsRemoved((CraftInventory) player.getInventory(), 36, _item); + } + else + { + InventoryUtil.removeItem((CraftInventory) player.getInventory(), 36, _item); + } + + int reward = amount * _sellPrice; + + GoldManager.getInstance().addGold(player, reward); + GoldManager.notify(player, String.format("You sold %d items for %dg", amount, reward)); + _page.playAcceptSound(player); + } + else if (clickType == ClickType.SHIFT_LEFT || clickType == ClickType.LEFT) + { + final int amount = !(UtilItem.isArmor(_item.getType()) || UtilItem.isTool(_item.getType()) || _item.getType() == Material.BOW) && shiftClick ? 64 : 1; + final int cost = amount * _buyPrice; + int goldCount = GoldManager.getInstance().getGold(player); + + if (goldCount >= cost) + { + final ItemStack eventItem = _item.clone(); + eventItem.setAmount(amount); + + GoldManager.getInstance().deductGold(success -> + { + if (success) + { + ClansPlayerBuyItemEvent event = new ClansPlayerBuyItemEvent(player, _page, ShopItemButton.this, eventItem, cost, amount); + UtilServer.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + GoldManager.getInstance().addGold(player, cost); + return; + } + + _item = event.getItem(); + final int finalCost = event.getCost(); + final int finalAmount = event.getAmount(); + + giftItem(player, finalAmount); + GoldManager.notify(player, String.format("You have purchased %d item(s) for %dg", finalAmount, finalCost)); + + _page.playAcceptSound(player); + } + else + { + GoldManager.notify(player, "You cannot afford that item! Please relog to update your gold count."); + _page.playDenySound(player); + } + + _page.refresh(); + }, player, cost); + } + else + { + GoldManager.notify(player, "You cannot afford that item."); + _page.playDenySound(player); + } + } + + _page.refresh(); + } + + private boolean hasItem(Player player, ItemStack item) + { + return InventoryUtil.first((CraftInventory) player.getInventory(), 36, item, true) != -1; + } + + private int getAmount(Player player, ItemStack item) + { + int amount = 0; + for (ItemStack stack : player.getInventory().getContents()) + { + if (stack == null) + { + continue; + } + + if (stack.equals(item)) + { + amount++; + } + } + + return amount; + } + + private void notify(Player player, String message) + { + UtilPlayer.message(player, F.main("Shop", message)); + } + + private void giftItem(Player player, int amount) + { + ItemStack item = _item.clone(); + item.setAmount(amount); + player.getInventory().addItem(item); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/BankPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/BankPage.java new file mode 100644 index 00000000..24962873 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/BankPage.java @@ -0,0 +1,135 @@ +package mineplex.game.clans.shop.bank; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.DisplayButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.shop.ClansShopItem; + +public class BankPage extends ShopPageBase +{ + public static final int GEM_CONVERSION = 1000; // The number of gems that can be converted into gold + public static final int TOKEN_VALUE = ClansShopItem.GOLD_TOKEN.getBuyPrice(); // Value of a GoldToken (in gold) that can be stored/cashed in here + private ClanInfo _clanInfo; + + public BankPage(ClansManager plugin, BankShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, "Bank Shop", player, 9); + _clanInfo = getPlugin().getClan(getPlayer()); + + buildPage(); + } + + @Override + protected void buildPage() + { + buildCashIn(); + + if (hasEnoughGold()) + { + buildTokenPurchasable(); + } + else + { + buildTokenUnpurchasable(); + } + + if (GoldManager.getInstance().canTransferGems(getPlayer())) + { + buildTransferGems(); + } + else + { + buildTransferGemsCooldown(); + } + } + + private void buildCashIn() + { + int playerGold = getPlayerGold(); + + CashInButton button = new CashInButton(this); + String title = "Cash In Gold Token"; + String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g"); + String description = ChatColor.RESET + C.cWhite + "Click with GoldToken to exchange for gold!"; + ShopItem shopItem = new ShopItem(Material.FURNACE, title, new String[] {" ", playerGoldString, description}, 0, true, true); + addButton(5, shopItem, button); + } + + private void buildTransferGems() + { + int playerGold = getPlayerGold(); + int playerGems = getPlayerGems(); + int conversionCount = (int) (GEM_CONVERSION * GoldManager.GEM_CONVERSION_RATE); + + GemTransferButton button = new GemTransferButton(this, GEM_CONVERSION); + String title = ChatColor.GOLD + C.Bold + "Convert Gems To Gold!"; + String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g"); + String playerGemString = ChatColor.RESET + F.value("Your Gems", playerGems + " gems"); + String purchaseString = ChatColor.RESET + F.value("Conversion Rate", GEM_CONVERSION + " gems for " + conversionCount + " gold"); + String goldString = ChatColor.RESET + C.cWhite + "Convert gems into gold coins once per day!"; + ShopItem shopItem = new ShopItem(Material.EMERALD, title, new String[] {" ", playerGoldString, playerGemString, purchaseString, goldString}, 0, true, true); + addButton(4, shopItem, button); + } + + private void buildTransferGemsCooldown() + { + DisplayButton button = new DisplayButton(); + String title = ChatColor.RED + C.Bold + "Conversion Cooldown!"; + String purchaseString = ChatColor.RESET + C.cWhite + "You have already converted gems into coins today"; + ShopItem shopItem = new ShopItem(Material.REDSTONE_BLOCK, title, new String[] {" ", purchaseString, " "}, 0, true, true); + addButton(4, shopItem, button); + } + + private void buildTokenPurchasable() + { + int playerGold = getPlayerGold(); + + StoreGoldButton button = new StoreGoldButton(this); + String title = ChatColor.GOLD + C.Bold + "Purchase Gold Token!"; + String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g"); + String purchaseString = ChatColor.RESET + F.value("Token Value", TOKEN_VALUE + "g"); + String goldString = ChatColor.RESET + C.cWhite + "Store your bank gold in the form of a gold token!"; + ShopItem shopItem = new ShopItem(Material.RABBIT_FOOT, title, new String[] {" ", playerGoldString, purchaseString, goldString}, 0, true, true); + addButton(3, shopItem, button); + } + + private void buildTokenUnpurchasable() + { + int playerGold = getPlayerGold(); + int goldCost = TOKEN_VALUE; + + DisplayButton button = new DisplayButton(); + String title = ChatColor.RED + C.Bold + "Missing Gold!"; + String playerGoldString = ChatColor.RESET + F.value("Your Gold", playerGold + "g"); + String purchaseString = ChatColor.RESET + C.cWhite + "You don't have enough gold"; + String goldString = ChatColor.RESET + C.cWhite + "You need " + C.cYellow + goldCost + C.cWhite + " gold to purchase a token."; + ShopItem shopItem = new ShopItem(Material.RABBIT_FOOT, title, new String[] {" ", playerGoldString, purchaseString, goldString}, 0, true, true); + addButton(3, shopItem, button); + } + + public boolean hasEnoughGold() + { + return getPlayerGold() >= TOKEN_VALUE; + } + + private int getPlayerGems() + { + return GoldManager.getInstance().getGems(getPlayer()); + } + + private int getPlayerGold() + { + return GoldManager.getInstance().getGold(getPlayer()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/BankShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/BankShop.java new file mode 100644 index 00000000..37392888 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/BankShop.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.shop.bank; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class BankShop extends ShopBase +{ + public BankShop(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Bank Shop"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new BankPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/CashInButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/CashInButton.java new file mode 100644 index 00000000..a5ce9d6c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/CashInButton.java @@ -0,0 +1,45 @@ +package mineplex.game.clans.shop.bank; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.economy.GoldToken; + +public class CashInButton implements IButton +{ + private BankPage _page; + + public CashInButton(BankPage page) + { + _page = page; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (clickType != ClickType.LEFT && clickType != ClickType.RIGHT) return; + + if (!Recharge.Instance.use(player, "Attempt Buy Clans Shop Item", 1500, false, false)) + { + return; + } + + ItemStack item = player.getItemOnCursor(); + CustomItem cursorItem = GearManager.parseItem(item); + + if (cursorItem instanceof GoldToken) + { + GoldToken token = (GoldToken) cursorItem; + GoldManager.getInstance().cashIn(player, token); + player.setItemOnCursor(null); // Delete the gold token on cursor + _page.playAcceptSound(player); + _page.refresh(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/GemTransferButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/GemTransferButton.java new file mode 100644 index 00000000..226fcfde --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/GemTransferButton.java @@ -0,0 +1,47 @@ +package mineplex.game.clans.shop.bank; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.Callback; +import mineplex.core.donation.DonationManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.economy.GoldToken; + +public class GemTransferButton implements IButton +{ + private BankPage _page; + private int _gemAmount; + + public GemTransferButton(BankPage page, int gemAmount) + { + _page = page; + _gemAmount = gemAmount; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (clickType != ClickType.LEFT) return; + + if (!Recharge.Instance.use(player, "Attempt Buy Clans Shop Item", 1500, false, false)) + { + return; + } + + if (GoldManager.getInstance().canTransferGems(player)) + { + GoldManager.getInstance().transferGemsToCoins(player, _gemAmount); + _page.refresh(); + } + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/StoreGoldButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/StoreGoldButton.java new file mode 100644 index 00000000..6d023085 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/bank/StoreGoldButton.java @@ -0,0 +1,36 @@ +package mineplex.game.clans.shop.bank; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.economy.GoldManager; + +public class StoreGoldButton implements IButton +{ + private BankPage _page; + + public StoreGoldButton(BankPage page) + { + _page = page; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (clickType != ClickType.LEFT) return; + + if (!Recharge.Instance.use(player, "Attempt Buy Clans Shop Item", 1500, false, false)) + { + return; + } + + if (_page.hasEnoughGold()) + { + int cost = BankPage.TOKEN_VALUE; + GoldManager.getInstance().purchaseToken(player, cost); + _page.refresh(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/building/BuildingPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/building/BuildingPage.java new file mode 100644 index 00000000..4eed915d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/building/BuildingPage.java @@ -0,0 +1,41 @@ +package mineplex.game.clans.shop.building; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.shop.ClansShopItem; +import mineplex.game.clans.shop.ClansShopPage; + +public class BuildingPage extends ClansShopPage +{ + public BuildingPage(ClansManager plugin, BuildingShop shop, CoreClientManager clientManager, DonationManager donationManager, org.bukkit.entity.Player player) + { + super(plugin, shop, clientManager, donationManager, "Building Supplies", player); + + buildPage(); + } + + @Override + protected void buildPage() + { + addShopItem(1, ClansShopItem.STONE); + addShopItem(2, ClansShopItem.SMOOTH_BRICK); + addShopItem(3, ClansShopItem.CRACKED_STONE_BRICK, (byte) 2); + addShopItem(4, ClansShopItem.COBBLESTONE); + + addShopItem(10, ClansShopItem.LOG, (byte) 0); + addShopItem(11, ClansShopItem.LOG, (byte) 1); + addShopItem(12, ClansShopItem.LOG, (byte) 2); + addShopItem(13, ClansShopItem.LOG, (byte) 3); + addShopItem(14, ClansShopItem.LOG_2, (byte) 0); + addShopItem(15, ClansShopItem.LOG_2, (byte) 1); + + addShopItem(19, ClansShopItem.SAND); + addShopItem(20, ClansShopItem.GLASS); + addShopItem(21, ClansShopItem.SANDSTONE); + addShopItem(22, ClansShopItem.DIRT); + addShopItem(23, ClansShopItem.NETHER_BRICK); + addShopItem(24, ClansShopItem.QUARTZ_BLOCK); + addShopItem(25, ClansShopItem.CLAY); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/building/BuildingShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/building/BuildingShop.java new file mode 100644 index 00000000..84f1d0e9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/building/BuildingShop.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.shop.building; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class BuildingShop extends ShopBase +{ + public BuildingShop(ClansManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Building Materials"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new BuildingPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyPage.java new file mode 100644 index 00000000..a5fe9fdd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyPage.java @@ -0,0 +1,91 @@ +package mineplex.game.clans.shop.energy; + +import java.util.ArrayList; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanEnergyManager; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.event.ClansShopAddButtonEvent; +import mineplex.game.clans.clans.event.EnergyPageBuildEvent; + +public class EnergyPage extends ShopPageBase +{ + public EnergyPage(ClanEnergyManager plugin, EnergyShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, "Energy Shop", player, 18); + buildPage(); + } + + @Override + protected void buildPage() + { + ClanInfo clanInfo = getPlugin().getClansManager().getClan(getPlayer()); + if (clanInfo == null) + buildNoClan(); + else + { + addInfo(clanInfo, 4); + buildPurchase(clanInfo); + } + } + + private void buildPurchase(ClanInfo clanInfo) + { + int energyPerMin = Math.max(1, clanInfo.getEnergyCostPerMinute()); + + int oneHourEnergy = energyPerMin * 60; + int oneDayEnergy = oneHourEnergy * 24; + int maxEnergy = clanInfo.getEnergyPurchasable(); + + EnergyPageBuildEvent event = new EnergyPageBuildEvent(getPlayer()); + + UtilServer.getServer().getPluginManager().callEvent(event); + + addButton(clanInfo, 11, oneHourEnergy, Material.REDSTONE, (byte) 0, event.free(), " ", ChatColor.RESET + "Purchase 1 Hour of Energy for your Clan", " ", ChatColor.RESET + (event.free() ? "FREE! (Tutorial)" : "Costs " + C.cGreen + getPlugin().convertEnergyToGold(oneHourEnergy) + "g")); + addButton(clanInfo, 13, oneDayEnergy, Material.REDSTONE_BLOCK, (byte) 0, event.free(), " ", ChatColor.RESET + "Purchase 1 Day of Energy for your Clan", " ", ChatColor.RESET + (event.free() ? "FREE! (Tutorial)" : "Costs " + C.cGreen + getPlugin().convertEnergyToGold(oneDayEnergy) + "g")); + addButton(clanInfo, 15, maxEnergy, Material.FURNACE, (byte) 0, event.free(), " ", ChatColor.RESET + "Max Out your Clan's Energy", " ", ChatColor.RESET + (event.free() ? "FREE! (Tutorial)" : "Costs " + C.cGreen + getPlugin().convertEnergyToGold(maxEnergy) + "g")); + } + + private void addInfo(ClanInfo clanInfo, int slot) + { + String itemName = clanInfo.getName(); + ArrayList lore = new ArrayList(); + lore.add(" "); + lore.add(C.cYellow + "Energy: " + ChatColor.RESET + clanInfo.getEnergy()); + lore.add(C.cYellow + "Drain: " + ChatColor.RESET + clanInfo.getEnergyCostPerMinute() * 60 + " per Hour"); + lore.add(C.cYellow + "Max Energy: " + ChatColor.RESET + clanInfo.getEnergyMax()); + if (clanInfo.getEnergyCostPerMinute() > 0) lore.add(C.cYellow + "Time Left: " + ChatColor.RESET + UtilTime.convertString((clanInfo.getEnergy() / clanInfo.getEnergyCostPerMinute()) * 60000L, 1, UtilTime.TimeUnit.FIT)); + + ShopItem shopItem = new ShopItem(Material.DIAMOND, itemName, lore.toArray(new String[0]), 1, false, false); + setItem(slot, shopItem); + } + + private void addButton(ClanInfo clanInfo, int slot, int energyAmount, Material material, byte data, boolean free, String... lore) + { + boolean locked = energyAmount > clanInfo.getEnergyPurchasable() || energyAmount == 0; + String itemName = "Purchase " + energyAmount + " Energy"; + + ShopItem shopItem = new ShopItem(material, itemName, lore, 1, locked, false); + + if (locked) + setItem(slot, shopItem); + else + addButton(slot, shopItem, new EnergyShopButton(getPlugin(), this, energyAmount, clanInfo, free ? 0 : getPlugin().convertEnergyToGold(energyAmount))); + } + + private void buildNoClan() + { + ShopItem shopItem = new ShopItem(Material.WOOD_SWORD, "No Clan!", new String[] { " ", ChatColor.RESET + "You need to be in a", ChatColor.RESET + "clan to purchase energy!" }, 1, false, false); + setItem(4, shopItem); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyShop.java new file mode 100644 index 00000000..0305725b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyShop.java @@ -0,0 +1,24 @@ +package mineplex.game.clans.shop.energy; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanEnergyManager; +import mineplex.game.clans.clans.ClansManager; + +public class EnergyShop extends ShopBase +{ + public EnergyShop(ClanEnergyManager plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Energy Shop"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new EnergyPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyShopButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyShopButton.java new file mode 100644 index 00000000..162be0a8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/energy/EnergyShopButton.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.shop.energy; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.confirmation.ConfirmationPage; +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.clans.ClanEnergyManager; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.event.PreEnergyShopBuyEvent; +import mineplex.game.clans.economy.GoldPurchaseProcessor; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public class EnergyShopButton implements IButton +{ + private static final ItemStack ICON = new ItemBuilder(Material.REDSTONE).setTitle(ChatColor.RESET + "Clan Energy").build(); + + private ClanEnergyManager _energyManager; + private EnergyPage _page; + private int _energyToPurchase; + private ClanInfo _clanInfo; + private int _cost; + + public EnergyShopButton(ClanEnergyManager energyManager, EnergyPage page, int energyToPurchase, ClanInfo clanInfo, int cost) + { + _energyManager = energyManager; + _clanInfo = clanInfo; + _energyToPurchase = energyToPurchase; + _page = page; + _cost = cost; + } + + @Override + public void onClick(final Player player, ClickType clickType) + { + if (!Recharge.Instance.use(player, "Attempt Buy Clans Shop Item", 1500, false, false)) + { + return; + } + + if (UtilServer.CallEvent(new PreEnergyShopBuyEvent(player, _energyToPurchase, _cost)).isCancelled()) + { + return; + } + + _page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new GoldPurchaseProcessor(player, _cost, _energyManager.getClansManager().getGoldManager(), () -> + { + _clanInfo.adjustEnergy(_energyToPurchase); + _page.refresh(); + + _energyManager.runAsync(() -> _energyManager.getClansManager().getClanDataAccess().updateEnergy(_clanInfo)); + + // Notify + _energyManager.getClansManager().messageClan(_clanInfo, F.main("Energy", F.name(player.getName()) + " purchased " + F.elem(_energyToPurchase + " Energy") + " for the clan")); + }), ICON)); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/farming/FarmingPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/farming/FarmingPage.java new file mode 100644 index 00000000..f21e3053 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/farming/FarmingPage.java @@ -0,0 +1,37 @@ +package mineplex.game.clans.shop.farming; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.shop.ClansShopPage; +import mineplex.game.clans.shop.ClansShopItem; + +public class FarmingPage extends ClansShopPage +{ + public FarmingPage(ClansManager plugin, FarmingShop shop, CoreClientManager clientManager, DonationManager donationManager, org.bukkit.entity.Player player) + { + super(plugin, shop, clientManager, donationManager, "Organic Produce", player, 18); + + buildPage(); + } + + @Override + protected void buildPage() + { + addShopItem(1, ClansShopItem.POTATO_ITEM); + addShopItem(2, ClansShopItem.MELON); + addShopItem(3, ClansShopItem.BREAD); + addShopItem(4, ClansShopItem.COOKED_BEEF); + addShopItem(5, ClansShopItem.GRILLED_PORK); + addShopItem(6, ClansShopItem.COOKED_CHICKEN); + addShopItem(7, ClansShopItem.FEATHER); + addShopItem(8, ClansShopItem.CARROT_ITEM); + addShopItem(10, ClansShopItem.MUSHROOM_SOUP); + addShopItem(11, ClansShopItem.SUGAR_CANE); + addShopItem(12, ClansShopItem.PUMPKIN); + addShopItem(13, ClansShopItem.STRING); + addShopItem(14, ClansShopItem.BONE); + addShopItem(15, ClansShopItem.ROTTEN_FLESH); + addShopItem(16, ClansShopItem.SPIDER_EYE); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/farming/FarmingShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/farming/FarmingShop.java new file mode 100644 index 00000000..375dff0a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/farming/FarmingShop.java @@ -0,0 +1,27 @@ +package mineplex.game.clans.shop.farming; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class FarmingShop extends ShopBase +{ + public FarmingShop(ClansManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Organic Produce"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new FarmingPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/mining/MiningPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/mining/MiningPage.java new file mode 100644 index 00000000..aa6a4d85 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/mining/MiningPage.java @@ -0,0 +1,29 @@ +package mineplex.game.clans.shop.mining; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.shop.ClansShopPage; +import mineplex.game.clans.shop.ClansShopItem; + +public class MiningPage extends ClansShopPage +{ + public MiningPage(ClansManager plugin, MiningShop shop, CoreClientManager clientManager, DonationManager donationManager, org.bukkit.entity.Player player) + { + super(plugin, shop, clientManager, donationManager, "Mining Shop", player, 9); + + buildPage(); + } + + @Override + protected void buildPage() + { + addShopItem(1, ClansShopItem.IRON_INGOT); + addShopItem(2, ClansShopItem.GOLD_INGOT); + addShopItem(3, ClansShopItem.DIAMOND); + addShopItem(4, ClansShopItem.LEATHER); + addShopItem(5, ClansShopItem.COAL); + addShopItem(6, ClansShopItem.REDSTONE); + addShopItem(7, ClansShopItem.LAPIS_BLOCK); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/mining/MiningShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/mining/MiningShop.java new file mode 100644 index 00000000..1af0cf15 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/mining/MiningShop.java @@ -0,0 +1,28 @@ +package mineplex.game.clans.shop.mining; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.shop.mining.MiningPage; + +public class MiningShop extends ShopBase +{ + public MiningShop(ClansManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Mining Shop"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new MiningPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/MountBuyButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/MountBuyButton.java new file mode 100644 index 00000000..a0838568 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/MountBuyButton.java @@ -0,0 +1,74 @@ +package mineplex.game.clans.shop.pvp; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.recharge.Recharge; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.clans.mounts.MountClaimToken; +import mineplex.game.clans.economy.GoldManager; + +public class MountBuyButton> implements IButton +{ + private int _buyPrice; + private ItemStack _item; + private T _page; + + public MountBuyButton(T page) + { + _page = page; + _buyPrice = 150000; + _item = new MountClaimToken(1, 1, 1, MountType.HORSE).toItem(); + } + + @Override + public void onClick(final Player player, ClickType clickType) + { + if (!Recharge.Instance.use(player, "Attempt Buy Clans Shop Item", 1500, false, false)) + { + return; + } + if (clickType == ClickType.SHIFT_LEFT || clickType == ClickType.LEFT) + { + int goldCount = GoldManager.getInstance().getGold(player); + + if (goldCount >= _buyPrice) + { + GoldManager.getInstance().deductGold(success -> + { + if (success) + { + giftItem(player, 1); + GoldManager.notify(player, String.format("You have purchased %d item(s) for %dg", 1, _buyPrice)); + + _page.playAcceptSound(player); + } + else + { + GoldManager.notify(player, "You cannot afford that item! Please relog to update your gold count."); + _page.playDenySound(player); + } + + _page.refresh(); + }, player, _buyPrice); + } + else + { + GoldManager.notify(player, "You cannot afford that item."); + _page.playDenySound(player); + } + } + + _page.refresh(); + } + + private void giftItem(Player player, int amount) + { + ItemStack item = _item.clone(); + item.setAmount(amount); + player.getInventory().addItem(item); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/PvpPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/PvpPage.java new file mode 100644 index 00000000..27d119e6 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/PvpPage.java @@ -0,0 +1,81 @@ +package mineplex.game.clans.shop.pvp; + +import org.bukkit.Material; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.donation.DonationManager; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.shop.ClansShopItem; +import mineplex.game.clans.shop.ClansShopPage; +import mineplex.game.clans.shop.pvp.tnt.TNTGenShop; + +public class PvpPage extends ClansShopPage +{ + public PvpPage(ClansManager plugin, PvpShop shop, CoreClientManager clientManager, DonationManager donationManager, org.bukkit.entity.Player player) + { + super(plugin, shop, clientManager, donationManager, "Pvp Gear", player); + + buildPage(); + } + + @Override + protected void buildPage() + { + addShopItem(9, ClansShopItem.GOLD_HELMET, "Mage Helmet"); + addShopItem(18, ClansShopItem.GOLD_CHESTPLATE, "Mage Chestplate"); + addShopItem(27, ClansShopItem.GOLD_LEGGINGS, "Mage Leggings"); + addShopItem(36, ClansShopItem.GOLD_BOOTS, "Mage Boots"); + + addShopItem(10, ClansShopItem.LEATHER_HELMET, "Assassin Helmet"); + addShopItem(19, ClansShopItem.LEATHER_CHESTPLATE, "Assassin Chestplate"); + addShopItem(28, ClansShopItem.LEATHER_LEGGINGS, "Assassin Leggings"); + addShopItem(37, ClansShopItem.LEATHER_BOOTS, "Assassin Boots"); + + addShopItem(11, ClansShopItem.CHAINMAIL_HELMET, "Ranger Helmet"); + addShopItem(20, ClansShopItem.CHAINMAIL_CHESTPLATE, "Ranger Chestplate"); + addShopItem(29, ClansShopItem.CHAINMAIL_LEGGINGS, "Ranger Leggings"); + addShopItem(38, ClansShopItem.CHAINMAIL_BOOTS, "Ranger Boots"); + + addShopItem(12, ClansShopItem.IRON_HELMET, "Knight Helmet"); + addShopItem(21, ClansShopItem.IRON_CHESTPLATE, "Knight Chestplate"); + addShopItem(30, ClansShopItem.IRON_LEGGINGS, "Knight Leggings"); + addShopItem(39, ClansShopItem.IRON_BOOTS, "Knight Boots"); + + addShopItem(13, ClansShopItem.DIAMOND_HELMET, "Brute Helmet"); + addShopItem(22, ClansShopItem.DIAMOND_CHESTPLATE, "Brute Chestplate"); + addShopItem(31, ClansShopItem.DIAMOND_LEGGINGS, "Brute Leggings"); + addShopItem(40, ClansShopItem.DIAMOND_BOOTS, "Brute Boots"); + + addShopItem(15, ClansShopItem.IRON_SWORD, "Iron Sword"); + addShopItem(16, ClansShopItem.DIAMOND_SWORD, "Power Sword"); + addShopItem(17, ClansShopItem.GOLD_SWORD, "Booster Sword"); + + addShopItem(24, ClansShopItem.IRON_AXE, "Iron Axe"); + addShopItem(25, ClansShopItem.DIAMOND_AXE, "Power Axe"); + addShopItem(26, ClansShopItem.GOLD_AXE, "Booster Axe"); + + addShopItem(33, ClansShopItem.BOW, "Standard Bow"); + addShopItem(34, ClansShopItem.ARROW, (byte) 0, "Arrows", 16); + + addButton(51 - 9, new ItemBuilder(Material.IRON_BARDING).setTitle(C.cGreenB + "Standard Mount").setLore(C.cRed, C.cYellow + "Left-Click" + C.cWhite + " to buy " + C.cGreen + "1", C.cWhite + "Costs " + C.cGreen + "150000g").build(), new MountBuyButton<>(this)); + + if (Clans.HARDCORE) + { + addShopItem(52 - 9, ClansShopItem.CANNON, C.cBlue + "Cannon"); + addShopItem(53 - 9, ClansShopItem.OUTPOST, C.cBlue + "Outpost"); + } + + addShopItem(51, ClansShopItem.ENCHANTMENT_TABLE, "Class Shop"); + + if (Clans.HARDCORE) + { + addShopItem(52, ClansShopItem.TNT, "TNT"); + addButton(53, new ItemBuilder(ClansShopItem.TNT_GENERATOR.getMaterial()).setTitle(C.cAqua + "Manage TNT Generator").build(), (player, click) -> + new TNTGenShop(_plugin, _clientManager, _donationManager).attemptShopOpen(player) + ); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/PvpShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/PvpShop.java new file mode 100644 index 00000000..e4367cd3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/PvpShop.java @@ -0,0 +1,22 @@ +package mineplex.game.clans.shop.pvp; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class PvpShop extends ShopBase +{ + public PvpShop(ClansManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Pvp Gear"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new PvpPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/tnt/TNTGenPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/tnt/TNTGenPage.java new file mode 100644 index 00000000..783146d1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/tnt/TNTGenPage.java @@ -0,0 +1,172 @@ +package mineplex.game.clans.shop.pvp.tnt; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.*; +import mineplex.core.donation.DonationManager; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.tntgenerator.TntGenerator; +import mineplex.game.clans.clans.tntgenerator.TntGeneratorManager; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.shop.ClansShopItem; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.inventory.ItemStack; + +public class TNTGenPage extends ShopPageBase +{ + public TNTGenPage(ClansManager plugin, TNTGenShop shop, CoreClientManager clientManager, DonationManager donationManager, org.bukkit.entity.Player player) + { + super(plugin, shop, clientManager, donationManager, "TNT Generator", player); + + buildPage(); + } + + @Override + protected void buildPage() + { + ClanInfo clan = _plugin.getClan(_player); + + if (clan == null) + { + _player.closeInventory(); + _player.playSound(_player.getLocation(), Sound.NOTE_BASS, 1, 1); + UtilPlayer.message(_player, F.main("Clans", "You must be in a clan to manage a TNT Generator.")); + return; + } + + if (clan.getGenerator() == null) + { + addButton(13, new ItemBuilder(Material.BREWING_STAND_ITEM).setTitle(C.cRed + "Buy TNT Generator").setLore(" ", C.cYellow + ClansShopItem.TNT_GENERATOR.getBuyPrice() + " Gold").build(), (player, click) -> + { + clearPage(); + buildPage(); + + // Check if generator is still null + // Prevents someone from buying a generator at the same time as another clan member does. + if (clan.getGenerator() != null) + { + _player.playSound(_player.getLocation(), Sound.NOTE_BASS, 1, 1); + UtilPlayer.message(_player, F.main("Clans", "Your clan already has a TNT Generator.")); + return; + } + + if (getPlugin().getGoldManager().Get(player).getBalance() >= ClansShopItem.TNT_GENERATOR.getBuyPrice()) + { + GoldManager.getInstance().deductGold(success -> + { + if (success) + { + UtilPlayer.message(player, F.main("Clans", "You purchased a " + F.elem("TNT Generator") + " for your Clan. You can now access it from the " + F.elem("PvP Shop") + ".")); + clan.inform(F.main("Clans", F.elem(player.getName()) + " purchased a " + F.elem("TNT Generator") + " for the Clan. You can now access it from the " + F.elem("PvP Shop") + "."), player.getName()); + + TntGenerator generator = new TntGenerator(player.getUniqueId().toString()); + clan.setGenerator(generator); + _plugin.getClanDataAccess().updateGenerator(clan, null); + } + else + { + UtilPlayer.message(player, F.main("Clans", "You can not afford to purchase a " + F.elem("TNT Generator") + " for your Clan.")); + _player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 1); + } + }, player, ClansShopItem.TNT_GENERATOR.getBuyPrice()); + } + else + { + UtilPlayer.message(player, F.main("Clans", "You can not afford to purchase a " + F.elem("TNT Generator") + " for your Clan.")); + _player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 1); + } + + clearPage(); + buildPage(); + }); + } + else + { + TntGenerator generator = clan.getGenerator(); + + String nextTnt = "Never"; + + if (generator.getStock() < 3) + { + nextTnt = UtilTime.MakeStr((TntGeneratorManager.SECONDS_PER_TNT - generator.getTicks()) * 1000); + } + + if (clan.getMembers().containsKey(generator.getBuyer())) + { + addButton(13, new ItemBuilder(Material.BREWING_STAND_ITEM) + .setTitle(C.cGreen + "TNT Generator") + .setLore( + " ", + C.cWhite + "Purchased by " + F.elem(clan.getMembers().get(generator.getBuyer()).getPlayerName()), + " ", + C.cWhite + "TNT Available: " + F.elem(generator.getStock()), + " ", + C.cWhite + "Next TNT: " + F.elem(nextTnt)).build(), (player, click) -> + { + clearPage(); + buildPage(); + } + ); + } + else + { + addButton(13, new ItemBuilder(Material.BREWING_STAND_ITEM) + .setTitle(C.cGreen + "TNT Generator") + .setLore( + " ", + C.cWhite + "TNT Available: " + F.elem(generator.getStock()), + " ", + C.cWhite + "Next TNT: " + F.elem(nextTnt)).build(), (player, click) -> + { + clearPage(); + buildPage(); + } + ); + } + + if (generator.getStock() == 0) + { + return; + } + + int[] indices = UtilUI.getIndicesFor(generator.getStock(), 2); + + for (int index : indices) + { + addButton(index, new ItemBuilder(Material.TNT).setTitle(C.cGreen + "Retrieve TNT").setLore(" ", "Click to collect this TNT.").build(), (player, click) -> + { + clearPage(); + buildPage(); + + if (generator.getStock() <= 0) + { + UtilPlayer.message(player, F.main("Clans", "Your " + F.elem("TNT Generator") + " no longer contains this piece of TNT.")); + _player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 1); + return; + } + + if (UtilInv.HasSpace(player, Material.TNT, 1)) + { + UtilPlayer.message(player, F.main("Clans", "You have successfully collected TNT from your " + F.elem("TNT Generator") + ".")); + clan.inform(F.main("Clans", F.elem(player.getName()) + " has collected TNT from the Clan's " + F.elem("TNT Generator") + "."), player.getName()); + player.getInventory().addItem(new ItemStack(Material.TNT, 1)); + generator.setStock(generator.getStock() - 1); + _player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1); + } + else + { + UtilPlayer.message(player, F.main("Clans", "You do not have enough sufficient space in your inventory to collect TNT.")); + _player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 1); + } + + clearPage(); + buildPage(); + + }); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/tnt/TNTGenShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/tnt/TNTGenShop.java new file mode 100644 index 00000000..4e54909a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/shop/pvp/tnt/TNTGenShop.java @@ -0,0 +1,22 @@ +package mineplex.game.clans.shop.pvp.tnt; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; + +public class TNTGenShop extends ShopBase +{ + public TNTGenShop(ClansManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "TNT Generator"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new TNTGenPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/Spawn.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/Spawn.java new file mode 100644 index 00000000..92da88b1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/Spawn.java @@ -0,0 +1,561 @@ +package mineplex.game.clans.spawn; + +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerVelocityEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilParticle; +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.common.util.UtilTime.TimeUnit; +import mineplex.core.common.weight.WeightSet; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; +import mineplex.minecraft.game.classcombat.item.event.WebTossEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class Spawn extends MiniPlugin +{ + public static final int SPAWN_RADIUS = 32; + public static final int SHOP_RADIUS = 48; + public static final long COMBAT_TAG_DURATION = 15000; + public static final Location ORIGIN = new Location(getSpawnWorld(), 0, 0, 0); + + private static Spawn _instance; + public static Spawn getInstance() { return _instance; } + + private WeightSet _spawns; + private WeightSet _shops; + private ClansManager _clansManager; + + private long _songEastLast = 0; + private long _songWestLast = 0; + + private long _songEastLength = 345000; //Blocks + private long _songWestLength = 185000; //Chirp + + public Spawn(JavaPlugin plugin, ClansManager clansManager) + { + super("Clan Spawn Zones", plugin); + + _instance = this; + _spawns = new WeightSet(getNorthSpawn(), getSouthSpawn()); + _shops = new WeightSet(getEastTown(), getWestTown()); + _clansManager = clansManager; + + getSpawnWorld().setGameRuleValue("doDaylightCycle", "true"); + } + + /** + * Cancel most fire-spread mechanics to prevent mass destruction and uncontrollable fires. + * @param event + */ + @EventHandler + public void onBlockIgnite(BlockIgniteEvent event) + { + if (event.getCause() != IgniteCause.FLINT_AND_STEEL) + { + event.setCancelled(true); + } + } + + /** + * Prevent liquids from flowing into Safe Zone areas. + * @param event + */ + @EventHandler + public void onWaterFlow(BlockFromToEvent event) + { + Block block = event.getToBlock(); + + if (block.isLiquid() && isSafe(block.getLocation())) + { + event.setCancelled(true); + } + } + + /** + * Prevent players from tossing Webs into spawn or from spawn. + * @param event + */ + @EventHandler + public void onWebToss(WebTossEvent event) + { + if (isSafe(event.getLocation())) + { + event.setCancelled(true); + } + else if (event.getThrower() instanceof Player) + { + Player thrower = (Player) event.getThrower(); + + if (isInSpawn(thrower)) + { + event.setCancelled(true); + attemptNotify(thrower, "You cannot throw webs while in a safe zone!"); + } + } + } + + /** + * Prevent Spawn blocks from burning + * @param event + */ + @EventHandler + public void onBlockBurn(BlockBurnEvent event) + { + if (isSafe(event.getBlock().getLocation())) + { + event.setCancelled(true); + } + } + + /** + * Prevent {@link ItemFrame}s from being broken inside Spawn. + * @param event + */ + @EventHandler + public void onItemFrameDestroyed(HangingBreakByEntityEvent event) + { + if (event.getEntity() instanceof ItemFrame) + { + if (isSafe(event.getEntity().getLocation())) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void onItemFrameDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity() instanceof ItemFrame) + { + if (isSafe(event.GetDamageeEntity().getLocation())) + { + event.SetCancelled("Item Frame Cancel"); + } + } + } + + @EventHandler + public void onItemFrameDamage(EntityDamageEvent event) + { + if (event.getEntity() instanceof ItemFrame) + { + if (isSafe(event.getEntity().getLocation())) + { + event.setCancelled(true); + } + } + } + + @EventHandler + public void Update(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (Player cur : UtilServer.getPlayers()) + { + if (isSafe(cur.getLocation())) + { + long lastDamager = _clansManager.getCombatManager().getLog(cur).GetLastCombatEngaged(); + long duration = System.currentTimeMillis() - lastDamager; + + if (!UtilTime.elapsed(lastDamager, COMBAT_TAG_DURATION)) + { + String message = ChatColor.RED + "Unsafe for " + + ChatColor.YELLOW + F.time(UtilTime.convertString(COMBAT_TAG_DURATION - duration, 1, TimeUnit.FIT)); + + UtilTextMiddle.display(null, message, 0, 20, 0, cur); + playUnsafeParticles(cur); + } + else if (!UtilTime.elapsed(lastDamager, COMBAT_TAG_DURATION + 600)) + { + UtilTextMiddle.display(null, ChatColor.GREEN + "Safe!", 0, 60, 20, cur); + } + } + } + } + + @EventHandler + public void ignoreVelocity(PlayerVelocityEvent event) + { + if (_clansManager.getClanUtility().isSafe(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onSkill(SkillTriggerEvent event) + { + if (!isSafe(event.GetPlayer().getLocation())) + { + _clansManager.getCombatManager().getLog(event.GetPlayer()).SetLastCombatEngaged(System.currentTimeMillis()); + } + } + + private void playUnsafeParticles(Player player) + { + UtilParticle.PlayParticle(UtilParticle.ParticleType.CRIT, player.getEyeLocation().add(0, 0.75d, 0), 0, 0, 0, 0.2f, 35, UtilParticle.ViewDist.NORMAL); + } + + /** + * Prevent players from targetting spawn protected players using skills + * @param event + */ + @EventHandler + public void onSkillTriggered(SkillTriggerEvent event) + { + if (event.GetTargets() == null) return; + + for (Entity entity : event.GetTargets()) + { + if (isInSpawn(entity)) + { + event.SetCancelled(true); + } + } + } + + /** + * Prevent players from activating skills while in Spawn + * @param event + */ + @EventHandler + public void onSkillTriggeredInSpawn(SkillTriggerEvent event) + { + Player player = event.GetPlayer(); + + if (isInSpawn(player)) + { + UtilPlayer.message(event.GetPlayer(), F.main("Safe Zone", "You cannot use " + F.skill(event.GetSkillName()) + " in " + F.elem("Safe Zone") + ".")); + event.SetCancelled(true); + } + } + + /** + * Ensure players respawn in Spawn locations. + * @param event + */ + @EventHandler + public void onRespawn(PlayerRespawnEvent event) + { + event.setRespawnLocation(getSpawnLocation()); + _clansManager.getCombatManager().getLog(event.getPlayer()).SetLastCombatEngaged(System.currentTimeMillis() - Spawn.COMBAT_TAG_DURATION); + } + + /* + @EventHandler + public void onPlayerFirstJoin(PlayerJoinEvent event) + { + if (!event.getPlayer().hasPlayedBefore()) // First time playing on server, teleport to a spawn + { + teleport(event.getPlayer(), getSpawnLocation(), 2); // Teleport player to spawn after 2-tick delay to prevent on-join bug + } + } + */ + + /** + * Prevent creatures from spawning inside Spawn + * @param event + */ + @EventHandler + public void onEntitySpawn(CreatureSpawnEvent event) + { + if (event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.CUSTOM && isSafe(event.getLocation())) + { + event.setCancelled(true); + } + } + + /** + * Despawns any monsters within a spawn zone every two seconds. + * @param event + */ + @EventHandler + public void onUpdateTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TWOSEC) return; + + for (LivingEntity entity : getSpawnWorld().getLivingEntities()) + { + if (entity.hasMetadata("CombatLogNPC")) + { + continue; + } + if (entity instanceof Monster) + { + Monster monster = (Monster) entity; + + if (isInSpawn(monster)) + { + monster.setHealth(0); + } + } + } + + String mobsEnabled = getSpawnWorld().getGameRuleValue("doMobSpawning"); + + if (mobsEnabled.equals("true")) + { + if (getSpawnWorld().getTime() < 12000) + { + getSpawnWorld().setGameRuleValue("doMobSpawning", "false"); + } + } + else + { + if (getSpawnWorld().getTime() > 12000) + { + getSpawnWorld().setGameRuleValue("doMobSpawning", "true"); + } + } + } + + /** + * Prevent entities from dying and dropping items inside spawn. + * @param event + */ + @EventHandler + public void onEntityDeath(EntityDeathEvent event) + { + if (event.getEntity() instanceof Monster) + { + Monster monster = (Monster) event.getEntity(); + + if (isInSpawn(monster)) + { +// int size = event.getDrops().size(); + event.getDrops().clear(); + } + } + } + + /** + * Prevent creatures from targetting players who are in Spawn + * @param event + */ + @EventHandler + public void onEntityTarget(EntityTargetEvent event) + { + if (event.getTarget() != null && isSafe(event.getTarget().getLocation())) + { + event.setCancelled(true); + } + } + + /** + * Prevent players from breaking blocks in spawn + * @param event + */ + @EventHandler + public void onBlockBreak(BlockBreakEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) return; + + if (isSafe(event.getBlock().getLocation()) || isInSpawn(event.getPlayer())) + { + event.setCancelled(true); + } + } + + /** + * Prevent players from atacking others while in spawn + * @param event + */ + @EventHandler + public void onPlayerAttack(CustomDamageEvent event) + { + Player victim = event.GetDamageePlayer(); + Player attacker = event.GetDamagerPlayer(true); // Get (potentially ranged) attacker + + // wat + if (victim == null) + { + return; + } + + if (attacker == null) + { + return; + } + + if (!isCombatTagged(victim)) + { + if (isInSpawn(victim)) + { + event.SetCancelled("Safe Zone"); + attemptNotify(attacker, "You cannot attack players who are in a safe zone!"); + return; + } + else if (isInSpawn(attacker) && !isCombatTagged(attacker)) + { + event.SetCancelled("Safe Zone"); + attemptNotify(attacker, "You cannot attack untagged players while in a safe zone!"); + return; + } + } + + System.out.println(event.GetCancellers()); + } + + public Location getSpawnLocation() + { + Location spawn = _spawns.generateRandom().clone(); + spawn.setWorld(getSpawnWorld()); + return spawn; + } + + public Set getSpawnLocations() + { + return _spawns.elements(); + } + + public Set getShopLocations() + { + return _shops.elements(); + } + + public boolean isSafe(Location location) + { + return _clansManager.getClanUtility().isSafe(location); // Check to see if location is in a SafeZone chunk + } + + private static boolean isInRadius(Location origin, Location location, int radius) + { + int xOffset = Math.abs(location.getBlockX() - origin.getBlockX()); + int zOffset = Math.abs(location.getBlockZ() - origin.getBlockZ()); + + return xOffset <= radius && zOffset <= radius; + } + + // this is basically just isSafe(); + public boolean isInSpawn(Entity entity) + { + return entity != null && isSafe(entity.getLocation()); + } + + public static World getSpawnWorld() + { + return Bukkit.getWorld("world"); + } + + public static Location getWestTown() + { + return new Location(getSpawnWorld(), -440.91, 68, 23.08); + } + + public static Location getWestTownCenter() + { + return new Location(getSpawnWorld(), -425, 69, 8); + } + + public static Location getEastTown() + { + return new Location(getSpawnWorld(), 440.91, 64, -23.08); + } + + public static Location getEastTownCenter() + { + return new Location(getSpawnWorld(), 425, 65, -8); + } + + public static Location getNorthSpawn() + { + return new Location(getSpawnWorld(), 8.5, 206, -393.5); + } + + public static Location getSouthSpawn() + { + return new Location(getSpawnWorld(), 8.5, 200, 390.5); + } + + public boolean isCombatTagged(Player player) + { + return !UtilTime.elapsed(_clansManager.getCombatManager().getLog(player).GetLastCombatEngaged(), Spawn.COMBAT_TAG_DURATION); + } + + public void teleport(final Player player, final Location location, int delay) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> + { + player.teleport(location); + }, delay); + } + + /** + * Attempts to send a {@code message} to {@code entity} if they are a {@link Player}. + * @param entity + * @param message + */ + private static void attemptNotify(Entity entity, String message) + { + if (entity instanceof Player) + { + Player player = (Player) entity; + UtilPlayer.message(player, F.main("Clans", message)); + } + } + + @EventHandler + public void playDatMusicALLDAYLONG(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (UtilTime.elapsed(_songEastLast, _songEastLength)) + { + getNorthSpawn().getWorld().playEffect(getNorthSpawn(), Effect.RECORD_PLAY, 2258); //Blocks + + _songEastLast = System.currentTimeMillis(); + } + + if (UtilTime.elapsed(_songWestLast, _songWestLength)) + { + getSouthSpawn().getWorld().playEffect(getSouthSpawn(), Effect.RECORD_PLAY, 2259); //Chirp + + _songWestLast = System.currentTimeMillis(); + } + } + + public ClansManager getClansManager() + { + return _clansManager; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelButton.java new file mode 100644 index 00000000..6e6dc9b8 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelButton.java @@ -0,0 +1,109 @@ +package mineplex.game.clans.spawn.travel; + +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.InventoryUtil; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.economy.GoldToken; +import mineplex.game.clans.shop.PvpItem; +import mineplex.game.clans.spawn.Spawn; + +public class TravelButton implements IButton +{ + + private static final String LEFT_CLICK_TRAVEL = C.cYellow + "Left-Click" + C.cWhite + " to Warp"; + + private TravelPage _page; + private Location _location; + private Material _iconMaterial; + private String _name; + private String[] _lore; + private byte _data; + + public TravelButton(TravelPage page, Location location, Material material, String name, String[] lore, byte data) + { + _data =data; + _page = page; + _location = location; + _iconMaterial = material; + _name = name; + _lore = lore; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (clickType != ClickType.LEFT) + { + return; + } + + if (_location == null) + { + return; + } + + if (player.getLocation().distance(_location) <= 64) + { + return; + } + + transportPlayer(player); + } + + public ItemStack generateButtonItem() + { + Object[] lore = + { + C.cWhite + " ", + LEFT_CLICK_TRAVEL, + C.cWhite + " ", + + }; + + + if (_lore != null) + { + lore = ArrayUtils.addAll(lore, _lore); + } + + String[] strLore = new String[lore.length]; + + int index = 0; + for (Object obj : lore) + { + strLore[index] = obj.toString(); + index++; + } + + ShopItem item = new ShopItem(_iconMaterial, (byte)_data, _name, strLore, 0, false, false); + return item; + } + + private void transportPlayer(Player player) + { + player.teleport(_location); + _page.playAcceptSound(player); + // TODO: Notify player? Effects here? + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelPage.java new file mode 100644 index 00000000..93deef21 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelPage.java @@ -0,0 +1,163 @@ +package mineplex.game.clans.spawn.travel; + +import java.util.Arrays; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilBlock; +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.shop.item.IButton; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.Clans; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.gui.ClanIcon; +import mineplex.game.clans.clans.siege.outpost.Outpost; +import mineplex.game.clans.shop.ClansShopItem; +import mineplex.game.clans.spawn.Spawn; + +public class TravelPage extends ShopPageBase +{ + public TravelPage(ClansManager plugin, TravelShop shop, CoreClientManager clientManager, DonationManager donationManager, org.bukkit.entity.Player player) + { + super(plugin, shop, clientManager, donationManager, "Travel", player, 45); + + buildPage(); + } + + @Override + protected void buildPage() + { + addTravelLocation(Spawn.getNorthSpawn(), getPlayer().getLocation().distance(Spawn.getNorthSpawn()) <= 64 ? Material.SKULL_ITEM : Material.IRON_SWORD, (getPlayer().getLocation().distance(Spawn.getNorthSpawn()) <= 64 ? C.cRedB : C.cGreenB) + "North Spawn", new String[] { + C.cWhite + "Spawns are locations where", + C.cWhite + "you respawn after dying.", + " ", + C.cWhite + "You cannot be attacked here,", + C.cWhite + "as they are Safe Zones.", + getPlayer().getLocation().distance(Spawn.getSouthSpawn()) <= 64 ? " " : "", + getPlayer().getLocation().distance(Spawn.getNorthSpawn()) <= 64 ? C.cRed + "You are already here." : "", + }, 4, getPlayer().getLocation().distance(Spawn.getNorthSpawn()) <= 64 ? (byte) 3 : (byte) 0); + + addTravelLocation(Spawn.getSouthSpawn(), getPlayer().getLocation().distance(Spawn.getSouthSpawn()) <= 64 ? Material.SKULL_ITEM : Material.IRON_SWORD, (getPlayer().getLocation().distance(Spawn.getSouthSpawn()) <= 64 ? C.cRedB : C.cGreenB) + "South Spawn", new String[] { + C.cWhite + "Spawns are locations where", + C.cWhite + "you respawn after dying.", + " ", + C.cWhite + "You cannot be attacked here,", + C.cWhite + "as they are Safe Zones.", + getPlayer().getLocation().distance(Spawn.getSouthSpawn()) <= 64 ? " " : "", + getPlayer().getLocation().distance(Spawn.getSouthSpawn()) <= 64 ? C.cRed + "You are already here." : "", + }, 22 + 9 + 9, getPlayer().getLocation().distance(Spawn.getSouthSpawn()) <= 64 ? (byte) 3 : (byte) 0); + + addTravelLocation(Spawn.getWestTown(), ClanIcon.CASTLE.getMaterial(), C.cDGreenB + "West Shop", new String[] { + C.cWhite + "Shops are locations where you", + C.cWhite + "can buy and sell all sorts of goods.", + " ", + C.cWhite + "You cannot be attacked here,", + C.cWhite + "as they are Safe Zones.", + }, 12 + 8, ClanIcon.CASTLE.getData()); + + addTravelLocation(Spawn.getEastTown(), ClanIcon.CASTLE.getMaterial(), C.cDGreenB + "East Shop", new String[] { + C.cWhite + "Shops are locations where you", + C.cWhite + "can buy and sell all sorts of goods.", + " ", + C.cWhite + "You cannot be attacked here,", + C.cWhite + "as they are Safe Zones.", + }, 14 + 10, ClanIcon.CASTLE.getData()); + + final ClanInfo clan = _plugin.getClan(getPlayer()); + + if (Clans.HARDCORE) + { + Outpost outpost = _plugin.getSiegeManager().getOutpostManager().Get(clan); + + addTravelLocation(outpost == null ? null : outpost.getCoreLocation().clone().add(0, 1, 0), ClansShopItem.OUTPOST.getMaterial(), (outpost == null ? C.cRedB : C.cDGreenB) + "Outpost", new String[] { + C.cWhite + "Teleport to your Clan's currently", + C.cWhite + "active Outpost.", + " ", + (outpost == null ? C.cRed + "Your Clan does not have an Outpost." : ""), + }, 8, ClanIcon.CASTLE.getData()); + } + + + + final ItemStack item = new ItemStack(Material.BED, 1); + ItemMeta meta = item.getItemMeta(); + + if (meta == null) + { + meta = Bukkit.getItemFactory().getItemMeta(item.getType()); + } + + if (clan == null) + { + meta.setDisplayName(C.cRedB + "Clan Home"); + meta.setLore(Arrays.asList(" ", C.cWhite + "You are not in a Clan.")); + } + else if (clan.getHome() == null) + { + meta.setDisplayName(C.cRedB + "Clan Home"); + meta.setLore(Arrays.asList(" ", C.cWhite + "Your Clan does not have a Home. ", (clan.getMembers().get(getPlayer().getUniqueId()).getRole().equals(ClanRole.ADMIN) || clan.getMembers().get(getPlayer().getUniqueId()).getRole().equals(ClanRole.LEADER) ? C.cWhite + "Type " + C.cYellow + "/c sethome" + C.cWhite + " to set a home" : "Ask your Clan's Leader to set a home."))); + } + else + { + if (UtilBlock.isValidBed(clan.getHome()) && clan.getHome().clone().add(0, 1, 0).getBlock().getType().equals(Material.AIR) && clan.getHome().clone().add(0, 2, 0).getBlock().getType().equals(Material.AIR)) + { + meta.setDisplayName(C.cGreenB + "Clan Home"); + meta.setLore(Arrays.asList(" ", C.cWhite + "Teleport to your Clan Home.")); + } + else + { + meta.setDisplayName(C.cRedB + "Clan Home"); + meta.setLore(Arrays.asList(" ", C.cWhite + "Your Clan's Home Bed has been", + C.cWhite + "destroyed, or is obstructed.")); + } + } + + item.setItemMeta(meta); + + addButton(22, item, new IButton() + { + public void onClick(Player player, ClickType clickType) + { + if (item.getItemMeta().getDisplayName().startsWith(C.cGreen)) + { + player.closeInventory(); + player.teleport(clan.getHome().clone().add(0, 1, 0)); + } + } + }); + + addButton(44, new ItemBuilder(new ItemStack(Material.WATCH, 1)).setTitle(C.cGoldB + "Mineplex Lobby").addLore(" ", C.cYellow + "Left-Click" + C.cWhite + " to Warp", " ", C.cWhite + "Return to the main Mineplex Lobby", " ", C.cWhite + "You can do this at any time by", C.cWhite + "typing " + C.cYellow + "/lobby" + C.cWhite + ".").build(), new IButton() + { + public void onClick(Player player, ClickType clickType) + { + Portal.getInstance().sendPlayerToGenericServer(player, GenericServer.HUB, Intent.PLAYER_REQUEST); + } + }); + } + + public void addTravelLocation(Location location, Material material, String name, String[] lore, int slot) + { + TravelButton button = new TravelButton(this, location, material, name, lore, (byte) 0); + addButton(slot, button.generateButtonItem(), button); + } + + public void addTravelLocation(Location location, Material material, String name, String[] lore, int slot, byte data) + { + TravelButton button = new TravelButton(this, location, material, name, lore, data); + addButton(slot, button.generateButtonItem(), button); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelShop.java new file mode 100644 index 00000000..34e98535 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/spawn/travel/TravelShop.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.spawn.travel; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.inventory.ItemStack; + +import com.google.common.collect.Sets; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.spawn.Spawn; + +public class TravelShop extends ShopBase +{ + public static final String[] TRAVEL_LOCATIONS = { "North Shop", "South Shop", "East Spawn", "West Spawn" }; + + public TravelShop(ClansManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Travel Hub"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new TravelPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } + + @Override + public boolean attemptShopOpen(Player player) + { + if (Spawn.getInstance().isCombatTagged(player)) + { + notify(player, "You cannot use the Travel Hub while combat tagged!"); + return false; + } + + return super.attemptShopOpen(player); + } + + /** + * Destroy lone instances of Travel buttons that are fetched into a non-shop + * inventory (via lag) + * + * @param event + */ + @EventHandler + public void onInventoryClickedd(InventoryClickEvent event) + { + ItemStack item = event.getCurrentItem(); + if (item == null || item.getItemMeta() == null || item.getItemMeta().getDisplayName() == null) + return; + else if (isPlayerInShop(event.getWhoClicked())) return; + + String displayName = event.getCurrentItem().getItemMeta().getDisplayName(); + for (String travelLocation : TRAVEL_LOCATIONS) + { + if (displayName.contains(travelLocation)) + { + event.setCurrentItem(null); + } + } + } + + private static void notify(Player player, String message) + { + UtilPlayer.message(player, F.main("Travel Hub", message)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/Tutorial.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/Tutorial.java new file mode 100644 index 00000000..81069bc2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/Tutorial.java @@ -0,0 +1,407 @@ +package mineplex.game.clans.tutorial; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.hologram.Hologram; +import mineplex.core.hologram.HologramManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.message.ClansMessageManager; +import mineplex.game.clans.tutorial.objective.Objective; +import mineplex.game.clans.tutorial.objective.ObjectiveListener; + +public abstract class Tutorial implements Listener, ObjectiveListener +{ + private HashMap _playerSessionMap; + + private JavaPlugin _plugin; + private HologramManager _hologram; + private ClansMessageManager _message; + private String _name; + private String _taskIdentifier; + private TutorialWorldManager _worldManager; + + // GUI Data + private Material _guiMaterial; + private byte _guiData; + + private List _objectives; + + public Tutorial(JavaPlugin plugin, ClansMessageManager message, HologramManager hologram, String name, String taskIdentifier, Material guiMaterial, byte data) + { + _plugin = plugin; + _message = message; + _hologram = hologram; + _name = name; + _taskIdentifier = taskIdentifier; + + _guiMaterial = guiMaterial; + _guiData = data; + + _playerSessionMap = new HashMap<>(); + _objectives = new ArrayList<>(); + } + + protected void addObjective(Objective objective) + { + _objectives.add(objective); + objective.addListener(this); + } + + public void start(Player player) + { + if (!canStart(player)) + { + return; + } + + System.out.println(String.format("Tutorial> [%s] started tutorial [%s]", player.getName(), getName())); + + TutorialSession session = new TutorialSession(); + TutorialRegion region = _worldManager == null ? null : _worldManager.getNextRegion(); + session.setRegion(region); + + _playerSessionMap.put(player, session); + + onStart(player); + + // Start at first objective! + setObjective(player, 0); + + + _objectives.forEach(objective -> objective.setup(player, region)); + } + + private void setObjective(Player player, int objective) + { + if (_objectives.size() <= objective) + throw new IndexOutOfBoundsException("Invalid objective index: " + objective + ", size: " + _objectives.size()); + + _playerSessionMap.get(player).setObjectiveIndex(objective); + _objectives.get(objective).start(player); + } + + public boolean isInTutorial(Player player) + { + return _playerSessionMap.containsKey(player); + } + + public JavaPlugin getPlugin() + { + return _plugin; + } + + public String getName() + { + return _name; + } + + public Material getGuiMaterial() + { + return _guiMaterial; + } + + public byte getGuiData() + { + return _guiData; + } + + public ClansMessageManager getMessage() + { + return _message; + } + + public final String getTaskIdentifier() + { + return "clans.tutorial." + _taskIdentifier; + } + + @Override + public void onObjectiveFinish(Player player, Objective objective) + { + int index = _objectives.indexOf(objective); + + assert index != -1; + + if (index + 1 >= _objectives.size()) + { + finish(player); + } + else + { + setObjective(player, index + 1); + } + } + + @Override + public void onObjectiveStart(Player player, Objective objective) + { + } + + @Override + public void onObjectivePlayerUpdate(Player player, Objective objective) + { + } + + protected final void finish(Player player) + { + _objectives.forEach(objective -> objective.clean(player, getRegion(player))); + + removePlayer(player); + + System.out.println(String.format("Tutorial> [%s] finished tutorial [%s]", player.getName(), getName())); + + playFinishEffects(player.getLocation()); + onFinish(player); + } + + private void quit(Player player) + { + _objectives.forEach(objective -> objective.clean(player, getRegion(player))); + + removePlayer(player); + + System.out.println(String.format("Tutorial> [%s] quit tutorial [%s]", player.getName(), getName())); + + onQuit(player); + } + + private void removePlayer(Player player) + { + TutorialSession session = _playerSessionMap.remove(player); + + if (session != null) + { + if (session.getRegion() != null) + { + _worldManager.returnRegion(session.getRegion()); + } + + if (session.getSpawnHologram() != null) + session.getSpawnHologram().stop(); + + session.getHolograms().forEach(Hologram::stop); + } + } + + public Set getPlayers() + { + return _playerSessionMap.keySet(); + } + + /** + * Called when the player finishes the tutorial + */ + protected abstract void onFinish(Player player); + + /** + * Called when the player starts the tutorial + */ + protected abstract void onStart(Player player); + + /** + * Called when a player quits the tutorial or leaves the game in the tutorial + */ + protected abstract void onQuit(Player player); + + protected abstract boolean canStart(Player player); + + public void unregisterAll() + { + HandlerList.unregisterAll(this); + _objectives.forEach(Objective::unregisterAll); + } + + public List getScoreboardLines(Player player) + { + ArrayList lines = new ArrayList<>(); + TutorialSession session = _playerSessionMap.get(player); + if (session != null) + { + lines.add(" "); + + int objectiveIndex = session.getObjectiveIndex(); + Objective currentObjective = _objectives.get(objectiveIndex); + lines.add(C.cGreenB + currentObjective.getName(player)); + lines.add(" "); + currentObjective.addScoreboardLines(player, lines); + } + return lines; + } + + public void setWorldManager(TutorialWorldManager worldManager) + { + _worldManager = worldManager; + } + + public TutorialWorldManager getWorldManager() + { + return _worldManager; + } + + public TutorialRegion getRegion(Player player) + { + if(player == null || !player.isOnline() || _playerSessionMap == null || _playerSessionMap.get(player) == null) return null; + return _playerSessionMap.get(player).getRegion(); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + if (isInTutorial(event.getPlayer())) + { + quit(event.getPlayer()); + } + } + + @EventHandler + public void onKick(PlayerKickEvent event) + { + if (isInTutorial(event.getPlayer())) + { + quit(event.getPlayer()); + } + } + + @EventHandler + public void onHungerChange(FoodLevelChangeEvent event) + { + if (event.getEntity() instanceof Player && isInTutorial(((Player) event.getEntity()))) + { + event.setFoodLevel(20); + } + } + + @EventHandler + public void displayDescription(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (Map.Entry entry : _playerSessionMap.entrySet()) + { + String prefix = entry.getValue().incrementAndGetColorTick() % 2 == 0 ? C.cWhite : C.cGreen; + Objective objective = _objectives.get(entry.getValue().getObjectiveIndex()); + UtilTextBottom.display(prefix + objective.getDescription(entry.getKey()), entry.getKey()); + } + } + + @EventHandler + public void displayText(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + for (Map.Entry entry : _playerSessionMap.entrySet()) + { + Player player = entry.getKey(); + Objective objective = _objectives.get(entry.getValue().getObjectiveIndex()); + + if (entry.getValue().incrementAndGetTextSeconds() < 20) + { + // 20 second delay between displaying. + return; + } + + objective.displayChatMessages(player); + } + } + + public void addHologram(Player player, Location location, String... text) + { + if (_playerSessionMap.containsKey(player)) + { + Hologram hologram = new Hologram(_hologram, location, text); + _playerSessionMap.get(player).getHolograms().add(hologram); + hologram.start(); + } + } + + public void setSpawnHologram(Player player, Location location, String... text) + { + if (_playerSessionMap.containsKey(player)) + { + TutorialSession session = _playerSessionMap.get(player); + if (session.getSpawnHologram() == null && !session.isRemovedHologram()) + { + Hologram hologram = new Hologram(_hologram, location, text); + session.setSpawnHologram(hologram); + hologram.start(); + } + else + { + session.getSpawnHologram().setText(text); + } + } + } + + public void removeSpawnHologram(Player player) + { + if (_playerSessionMap.containsKey(player)) + { + TutorialSession session = _playerSessionMap.get(player); + if (session.getSpawnHologram() != null) + { + session.getSpawnHologram().stop(); + session.setSpawnHologram(null); + } + + session.setRemovedHologram(true); + } + } + + public TutorialSession getTutorialSession(Player player) + { + return _playerSessionMap.get(player); + } + + private void playFinishEffects(Location location) + { + // Firework + UtilFirework.launchFirework( + location, + FireworkEffect.Type.STAR, + Color.GREEN, + true, + true, + null, + 1 + ); + + // Particles + UtilParticle.PlayParticle(UtilParticle.ParticleType.HAPPY_VILLAGER, + location, 0.5F, 0.5F, 0.5F, 1, 3, UtilParticle.ViewDist.LONG); + UtilParticle.PlayParticle(UtilParticle.ParticleType.ENCHANTMENT_TABLE, + location, 0.5F, 0.5F, 0.5F, 1, 3, UtilParticle.ViewDist.LONG); + UtilParticle.PlayParticle(UtilParticle.ParticleType.HEART, + location, 0.5F, 0.5F, 0.5F, 1, 3, UtilParticle.ViewDist.LONG); + UtilParticle.PlayParticle(UtilParticle.ParticleType.NOTE, + location, 0.5F, 0.5F, 0.5F, 1, 3, UtilParticle.ViewDist.LONG); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java new file mode 100644 index 00000000..398fe6de --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java @@ -0,0 +1,208 @@ +package mineplex.game.clans.tutorial; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.events.PlayerRecieveBroadcastEvent; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.donation.DonationManager; +import mineplex.core.hologram.HologramManager; +import mineplex.core.npc.NpcManager; +import mineplex.core.task.TaskManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.ScoreboardManager; +import mineplex.core.thereallyoldscoreboardapiweshouldremove.elements.ScoreboardElement; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.message.ClansMessageManager; +import mineplex.game.clans.tutorial.command.TutorialCommand; +import mineplex.game.clans.tutorial.gui.TutorialShop; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; + +public class TutorialManager extends MiniPlugin implements ScoreboardElement +{ + public enum Perm implements Permission + { + TUTORIAL_COMMAND, + START_TUTORIAL_COMMAND, + FINISH_TUTORIAL_COMMAND, + } + + private CoreClientManager _clientManager; + private DonationManager _donationManager; + private ClansMessageManager _clansMessageManager; + + private EnumMap _tutorialMap; + private EnumMap _shopMap; // Don't need to do anything with shops currently + + public TutorialManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, HologramManager hologram, ClansManager clansManager, NpcManager npcManager, TaskManager taskManager) + { + super("Clans Tutorial", plugin); + + _clientManager = clientManager; + _donationManager = donationManager; + _clansMessageManager = new ClansMessageManager(plugin); + + _tutorialMap = new EnumMap(TutorialType.class); + _shopMap = new EnumMap(TutorialType.class); + + addTutorial(TutorialType.MAIN, new ClansMainTutorial(plugin, clansManager, _clansMessageManager, hologram, npcManager, taskManager)); + + generatePermissions(); + } + + private void generatePermissions() + { + + if (UtilServer.isTestServer()) + { + PermissionGroup.PLAYER.setPermission(Perm.TUTORIAL_COMMAND, true, true); + } else + { + PermissionGroup.ADMIN.setPermission(Perm.TUTORIAL_COMMAND, true, true); + } + if (UtilServer.isTestServer()) + { + PermissionGroup.PLAYER.setPermission(Perm.FINISH_TUTORIAL_COMMAND, true, true); + } else + { + PermissionGroup.ADMIN.setPermission(Perm.FINISH_TUTORIAL_COMMAND, true, true); + } + PermissionGroup.DEV.setPermission(Perm.START_TUTORIAL_COMMAND, true, true); + } + + @EventHandler + public void broadcast(PlayerRecieveBroadcastEvent event) + { + if (!inTutorial(event.getPlayer())) + { + return; + } + + if (!event.getMessage().startsWith(C.cBlue + "Event>")) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void playerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + + if (inTutorial(player)) + { + player.sendMessage(F.main("Clans", "You are not allowed to speak while in a tutorial.")); + event.setCancelled(true); + return; + } + + event.getRecipients().removeIf(this::inTutorial); + } + + @Override + public void addCommands() + { + addCommand(new TutorialCommand(this)); + } + + private void addTutorial(TutorialType type, Tutorial tutorial) + { + if (_tutorialMap.containsKey(type)) + { + _tutorialMap.remove(type).unregisterAll(); + } + + _tutorialMap.put(type, tutorial); + _shopMap.put(type, new TutorialShop(this, _clientManager, _donationManager, tutorial)); + getPlugin().getServer().getPluginManager().registerEvents(tutorial, getPlugin()); + } + + public boolean inTutorial(Player player) + { + return getTutorial(player) != null; + } + + public Tutorial getTutorial(Player player) + { + for (Tutorial tutorial : _tutorialMap.values()) + { + if (tutorial.isInTutorial(player)) + return tutorial; + } + + return null; + } + + public void finishTutorial(Player player) + { + Tutorial tutorial = getTutorial(player); + if (tutorial != null) + { + tutorial.finish(player); + } + } + + public boolean startTutorial(Player player, TutorialType type) + { + if (inTutorial(player)) + { + UtilPlayer.message(player, F.main("Tutorial", "You are already in a tutorial")); + return false; + } + + if (_tutorialMap.containsKey(type)) + { + UtilPlayer.message(player, F.main("Tutorial", "Starting Tutorial: " + type.name())); + _tutorialMap.get(type).start(player); + return true; + } + + return false; + } + + public void openTutorialMenu(Player player, TutorialType type) + { + if (_shopMap.containsKey(type)) + { + _shopMap.get(type).attemptShopOpen(player); + } + } + + public ClansMessageManager getMessageManager() + { + return _clansMessageManager; + } + + public Tutorial getTutorial(TutorialType type) + { + return _tutorialMap.get(type); + } + + @Override + public List getLines(ScoreboardManager manager, Player player, List out) + { + Tutorial tutorial = getTutorial(player); + + if (tutorial != null) + { + out.clear(); + return tutorial.getScoreboardLines(player); + } + + return new ArrayList(0); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialRegion.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialRegion.java new file mode 100644 index 00000000..52285209 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialRegion.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.tutorial; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; + +import mineplex.core.common.block.DataLocationMap; +import mineplex.core.common.block.schematic.Schematic; + +public class TutorialRegion +{ + private final Schematic _schematic; + private final Location _origin; + private DataLocationMap _locationMap; + + protected TutorialRegion(Schematic schematic, Location origin) + { + _origin = origin; + _schematic = schematic; + + pasteSchematic(); + } + + public Location getOrigin() + { + return _origin; + } + + public DataLocationMap getLocationMap() + { + return _locationMap; + } + + private void pasteSchematic() + { + _locationMap = _schematic.paste(getOrigin(), false).getDataLocationMap(); + } + + /** + * Clear the schematic area. This shouldn't be needed + */ + @Deprecated + private void clearSchematic() + { + for (int x = 0; x < _schematic.getWidth(); x++) + { + for (int y = 0; y < _schematic.getHeight(); y++) + { + for (int z = 0; z < _schematic.getLength(); z++) + { + Block b = _origin.clone().add(x, y, z).getBlock(); + if (b.getType() != Material.AIR) + { + b.setTypeIdAndData(0, (byte) 0, false); + } + } + } + } + } + + protected void reset() + { + long start = System.currentTimeMillis(); + System.out.println("TutorialRegion starting reset..."); + pasteSchematic(); + System.out.println("TutorialRegion finished reset! Took " + (System.currentTimeMillis() - start) + "ms"); + + } + + @Override + public String toString() + { + return "TutorialRegion[" + _origin.toString() + "]"; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialSession.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialSession.java new file mode 100644 index 00000000..271db3e0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialSession.java @@ -0,0 +1,118 @@ +package mineplex.game.clans.tutorial; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; + +import mineplex.core.hologram.Hologram; + +public class TutorialSession +{ + private final long _startTime; + private int _objectiveIndex; + private TutorialRegion _region; + private List _hologramList = new ArrayList<>(); + private Location _homeLocation; + private int _colorTick; + private int _textSeconds; + private Location _mapTargetLocation; + private Hologram _spawnHologram; + private boolean _removedHologram; + + public TutorialSession() + { + _startTime = System.currentTimeMillis(); + } + + public List getHolograms() + { + return _hologramList; + } + + public int getObjectiveIndex() + { + return _objectiveIndex; + } + + public void setObjectiveIndex(int objectiveIndex) + { + _objectiveIndex = objectiveIndex; + } + + public TutorialRegion getRegion() + { + return _region; + } + + public void setRegion(TutorialRegion region) + { + _region = region; + } + + public Location getHomeLocation() + { + return _homeLocation; + } + + public void setHomeLocation(Location homeLocation) + { + _homeLocation = homeLocation; + } + + public int incrementAndGetColorTick() + { + return ++_colorTick; + } + + public void setTextSeconds(int seconds) + { + _textSeconds = seconds; + } + + public int incrementAndGetTextSeconds() + { + _textSeconds++; + return _textSeconds; + } + + public void setMapTargetLocation(Location location) + { + _mapTargetLocation = location; + } + + public Location getMapTargetLocation() + { + return _mapTargetLocation; + } + + public long getStartTime() + { + return _startTime; + } + + public long getElapsedTime() + { + return System.currentTimeMillis() - _startTime; + } + + public boolean isRemovedHologram() + { + return _removedHologram; + } + + public void setRemovedHologram(boolean removedHologram) + { + _removedHologram = removedHologram; + } + + public void setSpawnHologram(Hologram spawnHologram) + { + _spawnHologram = spawnHologram; + } + + public Hologram getSpawnHologram() + { + return _spawnHologram; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialType.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialType.java new file mode 100644 index 00000000..98411461 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialType.java @@ -0,0 +1,6 @@ +package mineplex.game.clans.tutorial; + +public enum TutorialType +{ + MAIN +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java new file mode 100644 index 00000000..e6714847 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialWorldManager.java @@ -0,0 +1,108 @@ +package mineplex.game.clans.tutorial; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.Stack; + +import org.bukkit.Bukkit; +import org.bukkit.Difficulty; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.UtilSchematic; +import mineplex.core.common.generator.VoidGenerator; +import mineplex.game.clans.tutorial.TutorialRegion; + +public class TutorialWorldManager extends MiniPlugin +{ + public static final int BLOCKS_BETWEEN_TUTORIALS = 1200; + + private final World _tutorialWorld; + private final Schematic _schematic; + private LinkedList _regionStack; + private TutorialRegion _centerRegion; + + public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException + { + super("Tutorial World", plugin); + + log("Creating Tutorial World"); + WorldCreator creator = new WorldCreator(worldName); + creator.generator(new VoidGenerator()); + _tutorialWorld = Bukkit.createWorld(creator); + _tutorialWorld.setDifficulty(Difficulty.EASY); + _tutorialWorld.setGameRuleValue("doDaylightCycle", "false"); + _tutorialWorld.setTime(6000); + _tutorialWorld.setAutoSave(false); + _tutorialWorld.setAmbientSpawnLimit(0); + _tutorialWorld.setMonsterSpawnLimit(0); + _tutorialWorld.setWaterAnimalSpawnLimit(0); + log("Tutorial World Created!"); + + log("Loading schematic - " + schematicName); + _schematic = UtilSchematic.loadSchematic(new File(schematicName)); + log("Finished loading schematic"); + + log("Populating Region Stack..."); + populateRegionStack(); + log("Finished loading Tutorial World Manager!"); + } + + private void populateRegionStack() + { + _regionStack = new LinkedList<>(); + + // Populate the stack with 100 available tutorial regions + for (int x = 0; x < 10; x++) + { + for (int z = 0; z < 10; z++) + { + long time = System.currentTimeMillis(); + double xLoc = (x) * BLOCKS_BETWEEN_TUTORIALS; // 1000x1000 regions + double zLoc = (z) * BLOCKS_BETWEEN_TUTORIALS; + + TutorialRegion region = new TutorialRegion(_schematic, new Location(_tutorialWorld, xLoc, 30, zLoc)); + if (x == 0 && z == 0) _centerRegion = region; + _regionStack.add(region); + System.out.println("Finished Generating Region: " + ((x * 10) + z) + ". Took " + (System.currentTimeMillis() - time) + " ms"); + } + } + } + + /** + * Get the next TutorialRegion in the stack. This region is prepared and ready for use in a tutorial + * @return + */ + public TutorialRegion getNextRegion() + { + return _regionStack.pop(); + } + + /** + * Notify the TutorialWorldManager that this TutorialRegion is no longer needed and should be cleaned up. + * The TutorialRegion should not be used after calling this method + */ + public void returnRegion(TutorialRegion region) + { + region.reset(); + _regionStack.push(region); + log("Returned " + region.toString()); + } + + public World getTutorialWorld() + { + return _tutorialWorld; + } + + public TutorialRegion getCenterRegion() + { + return _centerRegion; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/FinishCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/FinishCommand.java new file mode 100644 index 00000000..acb0fcb4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/FinishCommand.java @@ -0,0 +1,20 @@ +package mineplex.game.clans.tutorial.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.game.clans.tutorial.TutorialManager; + +public class FinishCommand extends CommandBase +{ + public FinishCommand(TutorialManager plugin) + { + super(plugin, TutorialManager.Perm.FINISH_TUTORIAL_COMMAND, "finish", "end"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.finishTutorial(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/StartCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/StartCommand.java new file mode 100644 index 00000000..71ce8c3e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/StartCommand.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.tutorial.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.tutorial.TutorialManager; +import mineplex.game.clans.tutorial.TutorialType; + +public class StartCommand extends CommandBase +{ + public StartCommand(TutorialManager plugin) + { + super(plugin, TutorialManager.Perm.START_TUTORIAL_COMMAND, "start"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args == null || args.length != 1) + { + UtilPlayer.message(caller, F.main("Tutorial", "/tutorial start ")); + return; + } + + TutorialType type = null; + + for (TutorialType check : TutorialType.values()) + { + if (check.name().equalsIgnoreCase(args[0])) + { + type = check; + } + } + + if (type != null) + { + Plugin.openTutorialMenu(caller, type); + } + else + { + UtilPlayer.message(caller, F.main("Tutorial", "Invalid Tutorial " + F.elem(args[0]))); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/TutorialCommand.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/TutorialCommand.java new file mode 100644 index 00000000..06979be3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/command/TutorialCommand.java @@ -0,0 +1,25 @@ +package mineplex.game.clans.tutorial.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.MultiCommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.tutorial.TutorialManager; + +public class TutorialCommand extends MultiCommandBase +{ + public TutorialCommand(TutorialManager plugin) + { + super(plugin, TutorialManager.Perm.TUTORIAL_COMMAND, "tutorial", "tut"); + + AddCommand(new StartCommand(plugin)); + AddCommand(new FinishCommand(plugin)); + } + + @Override + protected void Help(Player caller, String[] args) + { + UtilPlayer.message(caller, F.main("Tutorial", "/tutorial start ")); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/TutorialSelectPage.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/TutorialSelectPage.java new file mode 100644 index 00000000..6265bd79 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/TutorialSelectPage.java @@ -0,0 +1,43 @@ +package mineplex.game.clans.tutorial.gui; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.tutorial.Tutorial; +import mineplex.game.clans.tutorial.TutorialManager; +import mineplex.game.clans.tutorial.gui.button.DeclineButton; +import mineplex.game.clans.tutorial.gui.button.StartButton; + +public class TutorialSelectPage extends ShopPageBase +{ + public TutorialSelectPage(TutorialManager plugin, TutorialShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, shop.getTutorial().getName(), player, 45); + + buildPage(); + } + + @Override + protected void buildPage() + { + Tutorial tutorial = getShop().getTutorial(); + + String name = tutorial.getName(); + Material material = tutorial.getGuiMaterial(); + byte data = tutorial.getGuiData(); + + ShopItem infoItem = new ShopItem(material, data, name, new String[0], 0, false, false); + addItem(13, infoItem); + + ShopItem startItem = new ShopItem(Material.EMERALD_BLOCK, "Start " + tutorial.getName(), new String[0], 0, false, false); + addButton(27 + 6, startItem, new StartButton(tutorial)); + + ShopItem declineButton = new ShopItem(Material.REDSTONE_BLOCK, "Cancel", new String[0], 0, false, false); + addButton(27 + 2, declineButton, new DeclineButton()); + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/TutorialShop.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/TutorialShop.java new file mode 100644 index 00000000..29a8c62f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/TutorialShop.java @@ -0,0 +1,33 @@ +package mineplex.game.clans.tutorial.gui; + +import org.bukkit.entity.Player; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.tutorial.Tutorial; +import mineplex.game.clans.tutorial.TutorialManager; + +public class TutorialShop extends ShopBase +{ + private final Tutorial _tutorial; + + public TutorialShop(TutorialManager plugin, CoreClientManager clientManager, DonationManager donationManager, Tutorial tutorial) + { + super(plugin, clientManager, donationManager, tutorial.getName()); + + _tutorial = tutorial; + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new TutorialSelectPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } + + public Tutorial getTutorial() + { + return _tutorial; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/button/DeclineButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/button/DeclineButton.java new file mode 100644 index 00000000..e1b283fa --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/button/DeclineButton.java @@ -0,0 +1,15 @@ +package mineplex.game.clans.tutorial.gui.button; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.shop.item.IButton; + +public class DeclineButton implements IButton +{ + @Override + public void onClick(Player player, ClickType clickType) + { + player.closeInventory(); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/button/StartButton.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/button/StartButton.java new file mode 100644 index 00000000..8461ea66 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/gui/button/StartButton.java @@ -0,0 +1,28 @@ +package mineplex.game.clans.tutorial.gui.button; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.shop.item.IButton; +import mineplex.game.clans.tutorial.Tutorial; + +public class StartButton implements IButton +{ + private final Tutorial _tutorial; + + public StartButton(Tutorial tutorial) + { + _tutorial = tutorial; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if (!_tutorial.isInTutorial(player)) + { + _tutorial.start(player); + } + + player.closeInventory(); + } +} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/worldmap/WorldMapModule.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/map/TutorialMapManager.java similarity index 52% rename from Plugins[Modified]/Nautilus.Game.Arcade/game/modules/worldmap/WorldMapModule.java rename to Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/map/TutorialMapManager.java index 505ef91e..b7e9d9a9 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/worldmap/WorldMapModule.java +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/map/TutorialMapManager.java @@ -1,41 +1,38 @@ -package nautilus.game.arcade.game.modules.worldmap; +package mineplex.game.clans.tutorial.map; import java.io.File; -import java.util.AbstractMap.SimpleEntry; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.Iterator; import java.util.Map.Entry; -import net.minecraft.server.v1_8_R3.Block; -import net.minecraft.server.v1_8_R3.BlockPosition; -import net.minecraft.server.v1_8_R3.IBlockData; -import net.minecraft.server.v1_8_R3.MaterialMapColor; - import org.bukkit.Bukkit; import org.bukkit.Chunk; -import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.craftbukkit.v1_8_R3.CraftChunk; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.map.MapRenderer; import org.bukkit.map.MapView; +import org.bukkit.plugin.java.JavaPlugin; +import com.google.common.base.Objects; import com.google.common.collect.HashMultiset; import com.google.common.collect.Iterables; import com.google.common.collect.Multisets; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.common.util.C; +import mineplex.core.MiniPlugin; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilInv; import mineplex.core.common.util.UtilMath; @@ -44,89 +41,89 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.itemstack.ItemBuilder; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.TutorialManager; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.world.WorldData; +import net.minecraft.server.v1_8_R3.Block; +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.Blocks; +import net.minecraft.server.v1_8_R3.IBlockData; +import net.minecraft.server.v1_8_R3.MaterialMapColor; +import net.minecraft.server.v1_8_R3.PersistentCollection; -public class WorldMapModule extends Module +public class TutorialMapManager extends MiniPlugin { - - public enum Perm implements Permission - { - MAP_COMMAND - } - - private static final int BLOCK_SCAN_INTERVAL = 16; - - private int _halfMapSize; - private final int[][] _heightMap; + private ClansMainTutorial _tutorial; + private int _blocksScan = 16; + private Comparator> _comparator; + private int _halfMapSize = 64; + private int[][] _heightMap; private boolean _loadWorld = true; - private Map _map = new HashMap<>(); + private HashMap _map = new HashMap(); private short _mapId = (short) UtilMath.r(Short.MAX_VALUE); - private final List> _scanList = new ArrayList<>(); + private ArrayList> _scanList = new ArrayList>(); private World _world; - private int _centerX, _centerZ, _scale; + private int _centerX; + private int _centerZ; + private int _scale = 1; + private int _minX; + private int _minZ; - private final WorldMapRenderer _renderer; - - public WorldMapModule(WorldData worldData, WorldMapRenderer renderer) + public TutorialMapManager(JavaPlugin plugin, ClansMainTutorial tutorial, World world, int minX, int minZ, int maxX, int maxZ) { - this(worldData.World, worldData.MinX, worldData.MinZ, worldData.MaxX, worldData.MaxZ, renderer); - } + super("TutorialMapManager", plugin); - public WorldMapModule(World world, int minX, int minZ, int maxX, int maxZ, WorldMapRenderer renderer) - { _centerX = minX + ((maxX - minX) / 2); _centerZ = minZ + ((maxZ - minZ) / 2); _centerX = (int) (Math.round(_centerX / 16D) * 16); _centerZ = (int) (Math.round(_centerZ / 16D) * 16); - _renderer = renderer; - renderer.setManager(this); - - _halfMapSize = (int) (Math.ceil(Math.max((maxX - minX) / 2D, (maxZ - minZ) / 2D) / 16D) * 16); - - List> list = new ArrayList<>(); - - for (int scale = 1; scale <= 16; scale++) - { - int s = _halfMapSize; - - if ((s / scale) > 127) - { - continue; - } - - while (s < 10000 && (s % 16 != 0 || s % scale != 0)) - { - s += 16; - } - - if (s < 10000) - { - list.add(new SimpleEntry<>(scale, s)); - } - } - - if (list.isEmpty()) - { - _scale = 16; - _halfMapSize = 127 * 8; - } - else - { - list.sort(Comparator.comparingInt(Entry::getValue)); - - _scale = list.get(0).getKey(); - _halfMapSize = list.get(0).getValue(); - } + _tutorial = tutorial; + _minX = minX; + _minZ = minZ; _heightMap = new int[(_halfMapSize * 2) + 16][]; - for (int x = -_halfMapSize; x < _halfMapSize; x += BLOCK_SCAN_INTERVAL) + _comparator = new Comparator>() { - for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : BLOCK_SCAN_INTERVAL)) + + @Override + public int compare(Entry o1, Entry o2) { - _scanList.add(new SimpleEntry<>(x, z)); + // Render the places outside the map first to speed up visual errors fixing + int outsideMap = Boolean.compare(o1.getValue() < -_halfMapSize, o2.getValue() < -_halfMapSize); + + 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); + + } + }; + + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) + { + for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) + { + _scanList.add(new HashMap.SimpleEntry(x, z)); } } @@ -160,19 +157,25 @@ public class WorldMapModule extends Module try { - File dataFolder = new File("world/data"); + File foundFile = null; - if (dataFolder.exists()) + for (File f : new File("world/data").listFiles()) { - for (File file : dataFolder.listFiles()) + if (f.getName().startsWith("map_")) { - if (file.getName().startsWith("map_")) - { - file.delete(); - } + 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); + } + MapView view = Bukkit.createMap(_world); _mapId = view.getId(); setupRenderer(view); @@ -185,23 +188,6 @@ public class WorldMapModule extends Module rebuildScan(); } - @Override - protected void setup() - { - getGame().registerDebugCommand("map", Perm.MAP_COMMAND, PermissionGroup.PLAYER, (player, args) -> - { - if (UtilPlayer.isSpectator(player)) - { - return; - } - - Inventory inventory = player.getInventory(); - inventory.remove(Material.MAP); - inventory.addItem(getMapItem()); - player.sendMessage(F.main("Game", "Here, have a " + F.name("Map") + ".")); - }); - } - private void setupRenderer(MapView view) { for (MapRenderer renderer : view.getRenderers()) @@ -209,7 +195,7 @@ public class WorldMapModule extends Module view.removeRenderer(renderer); } - view.addRenderer(_renderer); + view.addRenderer(new TutorialMapRenderer(_tutorial, _minX, _minZ)); } public int getScale() @@ -227,17 +213,72 @@ public class WorldMapModule extends Module return _centerZ; } + @EventHandler + public void preventMapInItemFrame(PlayerInteractEntityEvent event) + { + if (!(event.getRightClicked() instanceof ItemFrame)) + return; + + ItemStack item = event.getPlayer().getItemInHand(); + + if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId || item.getDurability() != _mapId) + return; + + event.setCancelled(true); + } + + /** + * Get the center of the map. + */ + public int calcMapCenter(int zoom, int cord) + { + int mapSize = _halfMapSize / zoom; // This is how large the map is in pixels + + int mapCord = cord / zoom; // This is pixels from true center of map, not held map + + 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 zoom, int startingX, int startingZ) { - zoom = Math.max(zoom, 1); + if (zoom == 0) + zoom = 1; Byte[][] map = _map.get(zoom); - for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom) + for (int x = startingX; x < startingX + _blocksScan; 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++) @@ -254,8 +295,9 @@ public class WorldMapModule extends Module } } - for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom) + for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) { + // Water depth colors not included double d1 = 0; for (int addX = 0; addX < zoom; addX++) @@ -293,6 +335,22 @@ public class WorldMapModule extends Module } int origColor = map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / 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); map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; } @@ -304,9 +362,9 @@ public class WorldMapModule extends Module Byte[][] first = _map.get(1); Byte[][] second = _map.get(zoom); - for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom) + for (int x = startingX; x < startingX + _blocksScan; x += zoom) { - for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom) + for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) { HashMultiset hashmultiset = HashMultiset.create(); @@ -325,9 +383,7 @@ public class WorldMapModule extends Module Byte b = first[pX][pZ]; if (b == null) - { continue; - } hashmultiset.add(b); } @@ -340,6 +396,17 @@ public class WorldMapModule extends Module } } + @EventHandler + public void dropItem(ItemSpawnEvent event) + { + ItemStack item = event.getEntity().getItemStack(); + + if (item != null && item.getType() == Material.MAP && item.getDurability() == _mapId) + { + event.getEntity().remove(); + } + } + private double getDistance(double x1, double z1, double x2, double z2) { x1 = (x1 - x2); @@ -350,69 +417,112 @@ public class WorldMapModule extends Module private double getDistance(Entry entry, double x1, double z1) { - return getDistance(x1 + _centerX, z1 + _centerZ, entry.getKey() + (BLOCK_SCAN_INTERVAL / 2), entry.getValue() + (BLOCK_SCAN_INTERVAL / 2)); + return getDistance(x1 + _centerX, z1 + _centerZ, entry.getKey() + (_blocksScan / 2), + entry.getValue() + (_blocksScan / 2)); } - Byte[][] getMap(int scale) + public Byte[][] getMap(int scale) { return _map.get(scale); } + public int getMapSize() + { + return _halfMapSize; + } + + @EventHandler + public void preventMapMoveInventories(InventoryClickEvent event) + { + Inventory inv = event.getClickedInventory(); + + if (inv == null) + return; + + // Yeah, the loop looks a little weird.. + for (ItemStack item : new ItemStack[] + { + event.getCurrentItem(), + event.getCursor() + }) + { + if (item == null || item.getType() != Material.MAP || item.getDurability() != _mapId) + continue; + + if (inv.getHolder() instanceof Player ? !event.isShiftClick() : Objects.equal(event.getCurrentItem(), item)) + continue; + + event.setCancelled(true); + + UtilPlayer.message(event.getWhoClicked(), + F.main("Inventory", "You cannot move " + F.item("Clans Map") + " between inventories.")); + return; + } + } + private void rebuildScan() { - for (int x = -_halfMapSize; x < _halfMapSize; x += BLOCK_SCAN_INTERVAL) + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) { - for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : BLOCK_SCAN_INTERVAL)) + for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) { - _scanList.add(new SimpleEntry<>(x, z)); + _scanList.add(new HashMap.SimpleEntry(x, z)); } } if (!_loadWorld) { - _scanList.removeIf(entry -> + Iterator> itel = _scanList.iterator(); + + while (itel.hasNext()) { + Entry entry = itel.next(); + boolean removeEntry = true; + for (Player player : UtilServer.getPlayers()) { - Location location = player.getLocation(); - - if (getDistance(entry, location.getX(), location.getZ()) < 6400) + if (Math.sqrt(getDistance(entry, player.getLocation().getX(), player.getLocation().getZ())) < 200) { - return false; + removeEntry = false; + break; } } - return true; - }); + if (removeEntry) + { + itel.remove(); + } + } } + + Collections.sort(_scanList, _comparator); } @EventHandler public void renderMap(UpdateEvent event) { - if (event.getType() != UpdateType.TICK) - { + if (event.getType() != UpdateType.FASTEST) return; - } - - _renderer.renderTick(); if (_scanList.isEmpty()) { if (_loadWorld) { _loadWorld = false; - System.out.println("Finished rendering the map."); } - if (UtilServer.getPlayersCollection().size() == 0) - { + if (UtilServer.getPlayers().length == 0) return; - } rebuildScan(); - return; } + else if (_scanList.size() % 20 == 0) + { + Collections.sort(_scanList, _comparator); + } + + if (_scanList.isEmpty()) + return; Entry entry = _scanList.remove(0); @@ -435,17 +545,17 @@ public class WorldMapModule extends Module s = getScale(); if (s == 1) - { break; - } } if (s == 13 && _loadWorld) - { continue; + + if (!outsideMap) + { + drawWorldScale(s, startingX, startingZ); } - drawWorldScale(s, startingX, startingZ); colorWorldHeight(s, startingX, startingZ); } @@ -456,9 +566,10 @@ public class WorldMapModule extends Module { Byte[][] map = _map.get(1); - for (int beginX = startingX; beginX < startingX + BLOCK_SCAN_INTERVAL; beginX += 16) + for (int beginX = startingX; beginX < startingX + _blocksScan; beginX += 16) { - for (int beginZ = startingZ - (startingZ > -_halfMapSize ? 16 : 0); beginZ < startingZ + (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16) + for (int beginZ = startingZ - (startingZ > -_halfMapSize ? 16 : 0); beginZ < startingZ + + (setColors ? _blocksScan : 16); beginZ += 16) { Chunk chunk = _world.getChunkAt((beginX + _centerX) / 16, (beginZ + _centerZ) / 16); boolean loaded = false; @@ -489,7 +600,7 @@ public class WorldMapModule extends Module int l3 = z & 0xF; int l4 = nmsChunk.b(k3, l3) + 1; - IBlockData iblockdata; + IBlockData iblockdata = Blocks.AIR.getBlockData(); if (l4 > 1) { @@ -516,6 +627,7 @@ public class WorldMapModule extends Module if (setColors) { + // color = block.f(i5).M; IBlockData data = nmsChunk.getBlockData(new BlockPosition(k3, l4, l3)); color = data.getBlock().g(data).M; @@ -538,26 +650,31 @@ public class WorldMapModule extends Module } } - @EventHandler - public void inventoryClick(InventoryClickEvent event) + public void setMap(Player player) { - if (event.isCancelled()) + for (ItemStack item : UtilInv.getItems(player)) { - return; + if (item.getType() == Material.MAP && item.getDurability() == _mapId) + { + return; + } } - UtilInv.DisallowMovementOf(event, null, Material.MAP, (byte) _mapId, false); + ItemStack item = new ItemBuilder(Material.MAP, 1, _mapId).setTitle("Clans Map").build(); - if (event.isCancelled()) + int slot = player.getInventory().firstEmpty(); + + if (slot >= 0) { - event.getWhoClicked().sendMessage(F.main("Game", "You cannot move this map from your inventory.")); + ItemStack mapSlot = player.getInventory().getItem(8); + + if (mapSlot == null || mapSlot.getType() == Material.AIR) + { + slot = 8; + } + + player.getInventory().setItem(slot, item); } } - public ItemStack getMapItem() - { - return new ItemBuilder(Material.MAP, 1, _mapId) - .setTitle(C.cGreenB + "World Map") - .build(); - } -} \ No newline at end of file +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/map/TutorialMapRenderer.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/map/TutorialMapRenderer.java new file mode 100644 index 00000000..1132dd4a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/map/TutorialMapRenderer.java @@ -0,0 +1,243 @@ +package mineplex.game.clans.tutorial.map; + +import java.awt.*; +import java.util.List; + +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.tutorial.TutorialManager; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.TutorialType; +import mineplex.game.clans.tutorial.TutorialWorldManager; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; + +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; + +public class TutorialMapRenderer extends MapRenderer +{ + private ClansMainTutorial _tutorial; + private int _minX; + private int _minZ; + + public TutorialMapRenderer(ClansMainTutorial tutorialManager, int minX, int minZ) + { + super(true); + + _tutorial = tutorialManager; + _minX = minX; + _minZ = minZ; + } + + @Override + public void render(MapView mapView, MapCanvas canvas, Player player) + { + TutorialMapManager tutorialMap = _tutorial.getMapManager(); + int zoom = tutorialMap.getScale(); + + Byte[][] map = tutorialMap.getMap(zoom); + + int centerX = 0; + int centerZ = 0; + + // We have this cooldown to squeeze out every single bit of performance from the server. + if (Recharge.Instance.use(player, "Draw Map", 4000, false, false)) + { + TutorialRegion region = _tutorial.getWorldManager().getCenterRegion(); + MinMaxArea shops = getArea(region, ClansMainTutorial.Bounds.SHOPS); + MinMaxArea fields = getArea(region, ClansMainTutorial.Bounds.FIELDS); + MinMaxArea spawn = getArea(region, ClansMainTutorial.Bounds.SPAWN); + MinMaxArea claim = getArea(region, ClansMainTutorial.Bounds.LAND_CLAIM); + MinMaxArea enemy = getArea(region, ClansMainTutorial.Bounds.ENEMY_LAND); + + 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); + + int xRegion = mapX + _minX - 6; + int zRegion = mapZ + _minZ; + + Byte color = 0; + + + if (!(pixelX < 0 || pixelZ < 0 || pixelX >= map.length || pixelZ >= map.length) + && map[pixelX][pixelZ] != null) + { + color = map[pixelX][pixelZ]; + + if (!((color <= -113 || color >= 0) && color <= 127)) + color = (byte) 0; + + blockX *= zoom; + blockZ *= zoom; + + color = attemptDraw(false, color, Color.WHITE, new Color(50, 150, 255), xRegion, zRegion, shops, mapX, mapZ); + color = attemptDraw(false, color, Color.WHITE, new Color(255, 120, 0), xRegion, zRegion, fields, mapX, mapZ); + color = attemptDraw(false, color, Color.WHITE, new Color(0, 255, 100), xRegion, zRegion, spawn, mapX, mapZ); + color = attemptDraw(true, color, Color.CYAN, null, xRegion, zRegion, claim, mapX, mapZ); + color = attemptDraw(true, color, Color.RED, null, xRegion, zRegion, enemy, mapX, mapZ); + } + + /* TODO Figure out if you want to colorize this pixel + { + color = MapPalette.matchColor(r, g, b); + }*/ + + canvas.setPixel(mapX, mapZ, color); + } + } + + player.sendMap(mapView); + } + + MapCursorCollection cursors = canvas.getCursors(); + + while (cursors.size() > 0) + + { + cursors.removeCursor(cursors.getCursor(0)); + } + + Location l = player.getLocation().clone(); + l.setX((((int)l.getX()) % TutorialWorldManager.BLOCKS_BETWEEN_TUTORIALS) + (l.getX() - ((int) l.getX()))); + l.setZ((((int)l.getZ()) % TutorialWorldManager.BLOCKS_BETWEEN_TUTORIALS) + (l.getZ() - ((int) l.getZ()))); + + double mapX = (l.getX() - tutorialMap.getX()) / zoom; + double mapZ = (l.getZ() - tutorialMap.getZ()) / zoom; + + 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 rotation = (byte) (int) ((l.getYaw() * 16D) / 360D); + + MapCursor cursor = new MapCursor(b0, b1, (byte) (rotation & 0xF), MapCursor.Type.WHITE_POINTER.getValue(), true); + + cursors.addCursor(cursor); + } + + // Add Tutorial Markers + TutorialSession session = _tutorial.getTutorialSession(player); + if (session != null) + { + if (session.getMapTargetLocation() != null) + { + Location point = session.getMapTargetLocation().clone(); + point.setX((((int)point.getX()) % TutorialWorldManager.BLOCKS_BETWEEN_TUTORIALS) + (point.getX() - ((int) point.getX()))); + point.setZ((((int)point.getZ()) % TutorialWorldManager.BLOCKS_BETWEEN_TUTORIALS) + (point.getZ() - ((int) point.getZ()))); + mapX = (point.getX() - tutorialMap.getX()) / zoom; + mapZ = (point.getZ() - tutorialMap.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); + } + } + } + } + + private byte attemptDraw(boolean colorAll, byte color, Color color1, Color color2, int xRegion, int zRegion, MinMaxArea area, int mapX, int mapZ) + { + if (xRegion >= area.MinX && xRegion <= area.MaxX && zRegion >= area.MinZ && zRegion <= area.MaxZ) + { + if (xRegion == area.MinX || xRegion == area.MaxX || zRegion == area.MinZ || zRegion == area.MaxZ) + { + // Outer Ring + Color cColor = MapPalette.getColor(color); + double clans = colorAll ? 1 : 0.8;// 0.65; + + //Use clanColor2 no matter what for admins + Color drawColor = color1; + if (color2 != null) + { + drawColor = color2; + clans = 1; + } + + double base = 1 - clans; + + int r = (int) ((cColor.getRed() * base) + (drawColor.getRed() * clans)); + int b = (int) ((cColor.getBlue() * base) + (drawColor.getBlue() * clans)); + int g = (int) ((cColor.getGreen() * base) + (drawColor.getGreen() * clans)); + + color = MapPalette.matchColor(r, g, b); + } + else + { + // Inside + Color cColor = MapPalette.getColor(color); + + double clans = 0.065; + + //Stripes + boolean checker = (mapX + (mapZ % 4)) % 4 == 0; + Color drawColor = color1; +// if (colorAll) +// { +// clans = 0.8; +// } + if (checker && color2 != null && !colorAll) + { + drawColor = color2; + clans = 1; + } + + double base = 1 - clans; + + if (clans != 1 && (color == 0 || color == 1 || color == 2 || color == 3)) + return color; + + int r = (int) ((cColor.getRed() * base) + (drawColor.getRed() * clans)); + int b = (int) ((cColor.getBlue() * base) + (drawColor.getBlue() * clans)); + int g = (int) ((cColor.getGreen() * base) + (drawColor.getGreen() * clans)); + + color = MapPalette.matchColor(r, g, b); + } + } + + return color; + } + + private MinMaxArea getArea(TutorialRegion region, ClansMainTutorial.Bounds bounds) + { + MinMaxArea area = new MinMaxArea(); + List shopLocations = region.getLocationMap().getGoldLocations(bounds.getDataLocColor()); + area.MinX = Math.min(shopLocations.get(0).getBlockX(), shopLocations.get(1).getBlockX()); + area.MaxX = Math.max(shopLocations.get(0).getBlockX(), shopLocations.get(1).getBlockX()); + area.MinZ = Math.min(shopLocations.get(0).getBlockZ(), shopLocations.get(1).getBlockZ()); + area.MaxZ = Math.max(shopLocations.get(0).getBlockZ(), shopLocations.get(1).getBlockZ()); + + return area; + } + + private class MinMaxArea + { + public int MinX; + public int MaxX; + public int MinZ; + public int MaxZ; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/Objective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/Objective.java new file mode 100644 index 00000000..a5488a5a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/Objective.java @@ -0,0 +1,337 @@ +package mineplex.game.clans.tutorial.objective; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.game.clans.tutorial.Tutorial; +import mineplex.game.clans.tutorial.TutorialRegion; + +/** + * An Objective represents a set of goals that need to be completed to move on to the next Objective in the quest + */ +public abstract class Objective implements Listener +{ + private Plugin _plugin; + private JavaPlugin _javaPlugin; + private String _name; + private String _description; + private String _extraDescription; + private boolean _displayStartMessage; + private int _startMessageDelay; + private boolean _displayFinishMessage; + private int _finishMessageDelay; + + private NautHashMap _active; + private List _listeners; + + public Objective(Plugin plugin, JavaPlugin javaPlugin, String name, String description, String extraDescription) + { + _plugin = plugin; + _javaPlugin = javaPlugin; + _name = name; + _description = description; + _extraDescription = extraDescription; + _displayStartMessage = false; + _displayFinishMessage = false; + _startMessageDelay = 60; + _finishMessageDelay = 1; + + _active = new NautHashMap<>(); + _listeners = new LinkedList<>(); + + javaPlugin.getServer().getPluginManager().registerEvents(this, javaPlugin); + } + + public Objective(Plugin plugin, JavaPlugin javaPlugin, String name, String description) + { + this(plugin, javaPlugin, name, description, null); + } + + public Plugin getPlugin() + { + return _plugin; + } + + public JavaPlugin getJavaPlugin() + { + return _javaPlugin; + } + + /** + * Get the name of this Objective + */ + public String getName(Player player) + { + return _name; + } + + /** + * Get the description of this Objective + */ + public String getDescription(Player player) + { + return _description; + } + + /** + * Get the extra description for this Objective + * Extra description should be any additional useful information that isn't required to complete the objective + */ + public String getExtraDescription(Player player) + { + return _extraDescription; + } + + /** + * Add an ObjectiveListener to this Objective + * @param listener + */ + public void addListener(ObjectiveListener listener) + { + _listeners.add(listener); + } + + /** + * Remove all ObjectiveListeners from this Objective + */ + public void clearListeners() + { + _listeners.clear(); + } + + protected abstract void customStart(Player player); + + /** + * Start this Objective for a player + * @param player + */ + public void start(Player player) + { + System.out.println(String.format("Tutorial> [%s] started objective [%s]", player.getName(), getName(player))); + + Data data = createDataObject(player); + _active.put(player.getUniqueId(), data); + + _listeners.forEach(listener -> listener.onObjectiveStart(player, this)); + + if (_displayStartMessage) + Bukkit.getServer().getScheduler().runTaskLater(getJavaPlugin(), () -> showStartMessage(player), _startMessageDelay); + + customStart(player); + } + + /** + * Leave this objective for a specific player + * This does not count as completing the object + * @param player + */ + public final void leave(Player player) + { + customLeave(player); + + _active.remove(player.getUniqueId()); + + getGoals().forEach(goal -> goal.leave(player)); + } + + protected abstract void customLeave(Player player); + + /** + * Returns a new Data object for use in the active map + * @param player + * @return + */ + protected abstract Data createDataObject(Player player); + + /** + * Called by ObjectiveGoals, used to notify this Objective that a goal has been completed + * @param goal + * @param player + */ + protected abstract void completeGoal(ObjectiveGoal goal, Player player); + + /** + * Called when a player is finished the tutorial + * @param player + * @param region + */ + public void clean(Player player, TutorialRegion region) + { + List> goals = getGoals(); + if (goals != null) + goals.forEach(goal -> goal.clean(player, region)); + + _active.remove(player.getUniqueId()); + } + + /** + * Called when a player starts the tutorial + * @param player + * @param region + */ + public void setup(Player player, TutorialRegion region) + { + List> goals = getGoals(); + if (goals != null) + goals.forEach(goal -> goal.setup(player, region)); + } + + /** + * Returns a list of all the ObjectiveGoals used by this Objective + * Can return null + */ + protected abstract List> getGoals(); + + protected final void finish(Player player) + { + System.out.println(String.format("Tutorial> [%s] finished objective [%s]", player.getName(), getName(player))); + + _active.remove(player.getUniqueId()); + + if (_displayFinishMessage) + Bukkit.getServer().getScheduler().runTaskLater(getJavaPlugin(), () -> showFinishMessage(player), _finishMessageDelay); + + player.playSound(player.getEyeLocation(), Sound.LEVEL_UP, 1f, 1f); + + customFinish(player); + + _listeners.forEach(listener -> listener.onObjectiveFinish(player, this)); + } + + protected final void notifyUpdate(Player player) + { + _listeners.forEach(listener -> listener.onObjectivePlayerUpdate(player, this)); + } + + protected abstract void customFinish(Player player); + + public boolean contains(Player player) + { + return contains(player.getUniqueId()); + } + + public boolean contains(UUID uuid) + { + return _active.containsKey(uuid); + } + + protected final List getActive() + { + return new LinkedList(_active.keySet()); + } + + protected final Player[] getActivePlayers() + { + Set uuidSet = _active.keySet(); + Player[] players = new Player[uuidSet.size()]; + + int index = 0; + for (UUID uuid : uuidSet) + { + players[index] = UtilPlayer.searchExact(uuid); + index++; + } + return players; + } + + public Data getData(Player player) + { + return _active.get(player.getUniqueId()); + } + + /** + * Unregister all listeners associated with this Objective + */ + public final void unregisterAll() + { + HandlerList.unregisterAll(this); + + List> goals = getGoals(); + if (goals != null) goals.forEach(HandlerList::unregisterAll); + } + + public abstract void addScoreboardLines(Player player, List lines); + + private void showStartMessage(Player player) + { + UtilTextMiddle.display(C.cAqua + "Next Tutorial Section", getName(player), 20, 60, 20, player); + } + + private void showFinishMessage(Player player) + { + UtilTextMiddle.display(C.cGreen + "Tutorial Section Completed", getName(player), 20, 60, 20, player); + } + + public void displayChatMessages(Player player) + { + if (getPlugin().getTutorialSession(player) == null) + { + return; + } + + for (int i = 0; i < 1; i++) + { + UtilPlayer.message(player, ""); + } + + ObjectiveGoal goal = getLatestGoal(player); + String name = goal == null ? getName(player) : goal.getName(player); + String extra = getExtraDescription(player); +// UtilPlayer.message(player, C.cGold + C.Strike + "---------------------------------------------"); + UtilPlayer.message(player, C.cPurpleB + name); + if (extra != null) + { + UtilPlayer.message(player, ""); + UtilPlayer.message(player, C.cGray + " " + extra); + } + UtilPlayer.message(player, ""); + UtilPlayer.message(player, C.cGreen + getDescription(player)); +// UtilPlayer.message(player, C.cGold + C.Strike + "---------------------------------------------"); + getPlugin().getTutorialSession(player).setTextSeconds(0); + } + + public void setDisplayStartMessage(boolean displayStartMessage) + { + _displayStartMessage = displayStartMessage; + } + + public abstract ObjectiveGoal getLatestGoal(Player player); + + public void setDisplayFinishMessage(boolean displayFinishMessage) + { + _displayFinishMessage = displayFinishMessage; + } + + public int getStartMessageDelay() + { + return _startMessageDelay; + } + + public void setStartMessageDelay(int startMessageDelay) + { + _startMessageDelay = startMessageDelay; + } + + public int getFinishMessageDelay() + { + return _finishMessageDelay; + } + + public void setFinishMessageDelay(int finishMessageDelay) + { + _finishMessageDelay = finishMessageDelay; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveData.java new file mode 100644 index 00000000..9d6f8ca0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveData.java @@ -0,0 +1,5 @@ +package mineplex.game.clans.tutorial.objective; + +public class ObjectiveData +{ +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveGoal.java new file mode 100644 index 00000000..7a66d0a4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveGoal.java @@ -0,0 +1,232 @@ +package mineplex.game.clans.tutorial.objective; + +import java.util.*; + +import mineplex.core.common.util.UtilFirework; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import org.bukkit.*; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.TutorialRegion; + +public abstract class ObjectiveGoal > implements Listener +{ + private T _objective; + + private HashSet _active; + private HashSet _removeList; + private String _name; + private String _description; + private String _extraDescription; + private boolean _displayStartMessage; + private int _startMessageDelay; + private boolean _displayFinishMessage; + private int _finishMessageDelay; + private DyeColor _fireworkLocations; + + public ObjectiveGoal(T objective, String name, String description) + { + this(objective, name, description, null, null); + } + + public ObjectiveGoal(T objective, String name, String description, String extraDescription, DyeColor fireworkLocs) + { + _objective = objective; + + _active = new HashSet<>(); + _removeList = new HashSet<>(); + _name = name; + _description = description; + _extraDescription = extraDescription; + _displayStartMessage = true; + _startMessageDelay = 1;//40; + _displayFinishMessage = false; + _finishMessageDelay = 1; + _fireworkLocations = fireworkLocs; + } + + public String getName(Player player) + { + return _name; + } + + public String getDescription(Player player) + { + return _description; + } + + public String getExtraDescription(Player player) + { + return _extraDescription; + } + + public Set getActivePlayers() + { + return _active; + } + + public boolean contains(Player player) + { + if (player == null || !player.isOnline()) + { + return false; + } + + return _active.contains(player.getUniqueId()); + } + + public final void start(Player player) + { + System.out.println(String.format("Tutorial> [%s] started objective goal [%s]", player.getName(), getName(player))); + + _active.add(player.getUniqueId()); + + if (_displayStartMessage) + { + Bukkit.getServer().getScheduler().runTaskLater(_objective.getJavaPlugin(), () -> displayStartMessage(player), _startMessageDelay); + } + + customStart(player); + } + + protected abstract void customStart(Player player); + + protected abstract void customFinish(Player player); + + protected void customLeave(Player player) { } + + protected void leave(Player player) + { + if (_active.contains(player.getUniqueId())) + { + System.out.println(String.format("Tutorial> [%s] left objective goal [%s]", player.getName(), getName(player))); + + _removeList.add(player.getUniqueId()); + } + + customLeave(player); + } + + protected void finish(Player player) + { + if (_active.contains(player.getUniqueId())) + { + System.out.println(String.format("Tutorial> [%s] finished objective goal [%s]", player.getName(), getName(player))); + + if (getObjective().getPlugin().getTutorialSession(player) != null) + getObjective().getPlugin().getTutorialSession(player).setTextSeconds(0); + + _removeList.add(player.getUniqueId()); + + if (_displayFinishMessage) + { + Bukkit.getServer().getScheduler().runTaskLater(_objective.getJavaPlugin(), () -> displayFinishMessage(player), _finishMessageDelay); + } + + player.playSound(player.getEyeLocation(), Sound.ORB_PICKUP, 1f, 1f); + + customFinish(player); + + _objective.completeGoal(this, player); + } + } + + /** + * Called when a player starts the tutorial with this goal + */ + protected void setup(Player player, TutorialRegion region) + { + + } + + /** + * Called when a player finishes the tutorial with this goal + */ + protected void clean(Player player, TutorialRegion region) + { + _removeList.add(player.getUniqueId()); + } + + public T getObjective() + { + return _objective; + } + + protected void displayFinishMessage(Player player) + { + UtilTextMiddle.display(C.cGreen + "Completed Objective", getName(player), player); + } + + protected void displayStartMessage(Player player) + { + if (player == null || !player.isOnline()) + { + return; + } + + UtilTextMiddle.display(C.cYellow + "New Objective", getName(player), player); + + _objective.displayChatMessages(player); + } + + public void setDisplayStartMessage(boolean displayStartMessage) + { + _displayStartMessage = displayStartMessage; + } + + public void setDisplayFinishMessage(boolean displayFinishMessage) + { + _displayFinishMessage = displayFinishMessage; + } + + public void setStartMessageDelay(int startMessageDelay) + { + _startMessageDelay = startMessageDelay; + } + + public void setFinishMessageDelay(int finishMessageDelay) + { + _finishMessageDelay = finishMessageDelay; + } + + @EventHandler + public void update(UpdateEvent event) + { + if (!event.getType().equals(UpdateType.SEC_05)) return; + if (_fireworkLocations == null) return; + + for (UUID id : getActivePlayers()) + { + if (Bukkit.getPlayer(id) == null) continue; + List locations = getObjective().getPlugin().getRegion(Bukkit.getPlayer(id)).getLocationMap().getSpongeLocations(_fireworkLocations); + if (locations == null) continue; + for (Location loc : locations) + { + UtilFirework.playFirework(loc, FireworkEffect.Type.BURST, Color.AQUA, true, true); + } + } + } + + @EventHandler + public void activeCleaner(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + for (UUID uuid : _removeList) + { + _active.remove(uuid); + } + + _removeList.clear(); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveListener.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveListener.java new file mode 100644 index 00000000..59564fd3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/ObjectiveListener.java @@ -0,0 +1,23 @@ +package mineplex.game.clans.tutorial.objective; + +import org.bukkit.entity.Player; + +public interface ObjectiveListener +{ + /** + * Called when a player starts an objective + */ + public void onObjectiveStart(Player player, Objective objective); + + /** + * Called when a player progresses in an objective + * For example, in an OrderedObjective this will be called when the player + * moves to the next ObjectiveGoal + */ + public void onObjectivePlayerUpdate(Player player, Objective objective); + + /** + * Called when a player finishes an objective + */ + public void onObjectiveFinish(Player player, Objective objective); +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/OrderedObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/OrderedObjective.java new file mode 100644 index 00000000..450d3b16 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/OrderedObjective.java @@ -0,0 +1,133 @@ +package mineplex.game.clans.tutorial.objective; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.Tutorial; +import net.md_5.bungee.api.ChatColor; + +public abstract class OrderedObjective extends Objective +{ + private List> _goals; + + public OrderedObjective(Plugin plugin, JavaPlugin javaPlugin, String name, String description, String extraDescription) + { + super(plugin, javaPlugin, name, description, extraDescription); + + _goals = new ArrayList<>(); + } + + public OrderedObjective(Plugin plugin, JavaPlugin javaPlugin, String name, String description) + { + this(plugin, javaPlugin, name, description, null); + } + + protected void addGoal(ObjectiveGoal goal) + { + _goals.add(goal); + + getJavaPlugin().getServer().getPluginManager().registerEvents(goal, getJavaPlugin()); + } + + @Override + protected OrderedObjectiveData createDataObject(Player player) + { + return new OrderedObjectiveData(); + } + + @Override + protected void completeGoal(ObjectiveGoal goal, Player player) + { + int index = _goals.indexOf(goal); + + OrderedObjectiveData data = getData(player); + assert index == data.getIndex(); + + if (data == null || data.getIndex() + 1 >= _goals.size()) + { + finish(player); + } + else + { + setGoal(player, data.getIndex() + 1); + notifyUpdate(player); + } + } + + @Override + public String getDescription(Player player) + { + OrderedObjectiveData data = getData(player); + int index = data == null ? 0 : data.getIndex(); + return _goals.get(index).getDescription(player); + } + + @Override + public String getExtraDescription(Player player) + { + OrderedObjectiveData data = getData(player); + int index = data == null ? 0 : data.getIndex(); + return _goals.get(index).getExtraDescription(player); + } + + @Override + public ObjectiveGoal getLatestGoal(Player player) + { + OrderedObjectiveData data = getData(player); + int index = data == null ? 0 : data.getIndex(); + return _goals.get(index); + } + + @Override + protected void customStart(Player player) + { + setGoal(player, 0); + } + + @Override + protected void customLeave(Player player) + { + + } + + private void setGoal(Player player, int index) + { + OrderedObjectiveData data = getData(player); // Should never be null! + ObjectiveGoal nextGoal = _goals.get(index); + data.setIndex(index); + nextGoal.start(player); + } + + @Override + protected List> getGoals() + { + return _goals; + } + + @Override + public void addScoreboardLines(Player player, List lines) + { + if (contains(player)) + { + OrderedObjectiveData data = getData(player); +// lines.add(" " + getName()); + + for (int i = 0; i < _goals.size(); i++) + { + String prefix; + + if (i > data.getIndex()) + prefix = ChatColor.RED.toString(); + else if (i == data.getIndex()) + prefix = ">" + ChatColor.YELLOW.toString(); + else + prefix = ChatColor.GREEN.toString(); + + lines.add(" " + prefix + _goals.get(i).getName(player)); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/OrderedObjectiveData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/OrderedObjectiveData.java new file mode 100644 index 00000000..55fdd79d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/OrderedObjectiveData.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.tutorial.objective; + +public class OrderedObjectiveData extends ObjectiveData +{ + private int _index; + + public OrderedObjectiveData() + { + _index = 0; + } + + public int getIndex() + { + return _index; + } + + public void setIndex(int index) + { + _index = index; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/SingleObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/SingleObjective.java new file mode 100644 index 00000000..78e47d64 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/SingleObjective.java @@ -0,0 +1,61 @@ +package mineplex.game.clans.tutorial.objective; + +import java.util.List; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.C; +import mineplex.game.clans.tutorial.Tutorial; + +public abstract class SingleObjective extends Objective +{ + private final ObjectiveData _nullData; + + public SingleObjective(Plugin plugin, JavaPlugin javaPlugin, String name, String description, String extraDescription) + { + super(plugin, javaPlugin, name, description, extraDescription); + + _nullData = new ObjectiveData(); + } + + public SingleObjective(Plugin plugin, JavaPlugin javaPlugin, String name, String description) + { + this(plugin, javaPlugin, name, description, null); + } + + @Override + protected ObjectiveData createDataObject(Player player) + { + return _nullData; + } + + @Override + protected void completeGoal(ObjectiveGoal goal, Player player) + { + // Do Nothing + } + + @Override + public ObjectiveGoal getLatestGoal(Player player) + { + return null; + } + + @Override + protected List> getGoals() + { + return null; + } + + @Override + public void addScoreboardLines(Player player, List lines) + { + /* + if (contains(player)) + { + lines.add(" " + C.cRed + getName(player)); + } + */ + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/UnorderedObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/UnorderedObjective.java new file mode 100644 index 00000000..f145c227 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/UnorderedObjective.java @@ -0,0 +1,124 @@ +package mineplex.game.clans.tutorial.objective; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.Tutorial; +import net.md_5.bungee.api.ChatColor; + +public abstract class UnorderedObjective extends Objective +{ + private List> _goals; + + public UnorderedObjective(Plugin plugin, JavaPlugin javaPlugin, String name, String description, String extraDescription) + { + super(plugin, javaPlugin, name, description, extraDescription); + + _goals = new ArrayList<>(); + } + + public UnorderedObjective(Plugin plugin, JavaPlugin javaPlugin, String name, String description) + { + this(plugin, javaPlugin, name, description, null); + } + + protected void addGoal(ObjectiveGoal goal) + { + _goals.add(goal); + + getJavaPlugin().getServer().getPluginManager().registerEvents(goal, getJavaPlugin()); + } + + @Override + protected UnorderedObjectiveData createDataObject(Player player) + { + return new UnorderedObjectiveData(_goals.size()); + } + + @Override + protected void completeGoal(ObjectiveGoal goal, Player player) + { + int index = _goals.indexOf(goal); + + UnorderedObjectiveData data = getData(player); + data.setComplete(index); + + if (data.isComplete()) + { + finish(player); + } + else + { + notifyUpdate(player); + } + } + + @Override + public String getDescription(Player player) + { + UnorderedObjectiveData data = getData(player); + if (data == null) return super.getDescription(player); + int index = data.getFirstIncompleteIndex(); + return index == -1 ? super.getDescription(player) : _goals.get(index).getDescription(player); + } + + @Override + public String getExtraDescription(Player player) + { + UnorderedObjectiveData data = getData(player); + if (data == null) return super.getExtraDescription(player); + int index = data.getFirstIncompleteIndex(); + return index == -1 ? super.getExtraDescription(player) : _goals.get(index).getExtraDescription(player); + } + + @Override + public ObjectiveGoal getLatestGoal(Player player) + { + UnorderedObjectiveData data = getData(player); + if (data == null) return null; + int index = data.getFirstIncompleteIndex(); + return index == -1 ? null : _goals.get(index); + } + + @Override + protected void customStart(Player player) + { + _goals.forEach(goal -> goal.start(player)); + } + + @Override + protected void customLeave(Player player) + { + + } + + @Override + protected List> getGoals() + { + return _goals; + } + + @Override + public void addScoreboardLines(Player player, List lines) + { + if (contains(player)) + { + UnorderedObjectiveData data = getData(player); +// lines.add(" " + getName()); + + for (int i = 0; i < _goals.size(); i++) + { + String prefix; + if (data.isComplete(i)) + prefix = ChatColor.GREEN.toString(); + else + prefix = ChatColor.RED.toString(); + + lines.add(" " + prefix + _goals.get(i).getName(player)); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/UnorderedObjectiveData.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/UnorderedObjectiveData.java new file mode 100644 index 00000000..1d3bf705 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/objective/UnorderedObjectiveData.java @@ -0,0 +1,48 @@ +package mineplex.game.clans.tutorial.objective; + +public class UnorderedObjectiveData extends ObjectiveData +{ + private boolean[] _tasks; + + public UnorderedObjectiveData(int taskSize) + { + _tasks = new boolean[taskSize]; + } + + public boolean isComplete() + { + boolean complete = true; + for (int i = 0; i < _tasks.length; i++) + { + complete = complete && _tasks[i]; + } + return complete; + } + + public void setComplete(int taskId) + { + _tasks[taskId] = true; + } + + public boolean isComplete(int taskId) + { + return _tasks[taskId]; + } + + public int getFirstIncompleteIndex() + { + for (int i = 0; i < _tasks.length; i++) + { + if (_tasks[i] == false) + return i; + } + + return -1; + } + + public boolean[] getTasks() + { + return _tasks; + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java new file mode 100644 index 00000000..8fc0f0b9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java @@ -0,0 +1,625 @@ +package mineplex.game.clans.tutorial.tutorials.clans; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.collect.Lists; +//import mineplex.game.clans.tutorial.tutorials.clans.repository.TutorialRepository; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.hologram.HologramManager; +import mineplex.core.npc.NpcManager; +import mineplex.core.task.TaskManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.clans.event.ClansPlayerBuyItemEvent; +import mineplex.game.clans.clans.event.ClansPlayerSellItemEvent; +import mineplex.game.clans.clans.event.PreEnergyShopBuyEvent; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import mineplex.game.clans.economy.GoldManager; +import mineplex.game.clans.message.ClansMessageManager; +import mineplex.game.clans.spawn.Spawn; +import mineplex.game.clans.tutorial.Tutorial; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.TutorialWorldManager; +import mineplex.game.clans.tutorial.map.TutorialMapManager; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClassesObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.EnergyObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FieldsObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FinalObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.PurchaseItemsObjective; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ShopsObjective; + +public class ClansMainTutorial extends Tutorial +{ + // The distance from which the gate opens when a player approaches. + private static final int GATE_OPEN_DISTANCE = 15; + + private TutorialMapManager _mapManager; + private List _fireworks; +// private TutorialRepository _repository; + private TaskManager _taskManager; + + + private List _items = Lists.newArrayList( + Material.SMOOTH_BRICK, + Material.TORCH, + Material.IRON_DOOR, + Material.IRON_DOOR_BLOCK + ); + + + public ClansMainTutorial(JavaPlugin plugin, ClansManager clansManager, ClansMessageManager message, HologramManager hologram, NpcManager npcManager, TaskManager taskManager) + { + super(plugin, message, hologram, "Clans Tutorial", "main", Material.DIAMOND_SWORD, (byte) 0); + + _fireworks = new ArrayList<>(); + + try + { + setWorldManager(new TutorialWorldManager(plugin, "main_tutorial", "schematic/ClansTutorial.schematic")); + } + catch (IOException e) + { + e.printStackTrace(); + } + + _mapManager = new TutorialMapManager(plugin, this, getWorldManager().getTutorialWorld(), -10, 0, 117, 127); + _taskManager = taskManager; + +// _repository = new TutorialRepository(ClansManager.getInstance().getClientManager()); + + addObjective(new ClanObjective(this, plugin)); + addObjective(new AttackEnemyObjective(this, clansManager, plugin)); + addObjective(new ShopsObjective(this, npcManager, plugin)); + addObjective(new PurchaseItemsObjective(this, plugin)); + addObjective(new ClassesObjective(this, plugin)); + addObjective(new FieldsObjective(this, plugin)); + addObjective(new EnergyObjective(this, plugin)); + addObjective(new FinalObjective(this, plugin)); + } + + @Override + protected void onFinish(Player player) + { + _fireworks.add(player); + UtilTextMiddle.display(C.cYellow + "Congratulations", "You have completed the Tutorial!", 10, 60, 10, player); + + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> + { + _fireworks.remove(player); + getMessage().removePlayer(player); + + player.teleport(Spawn.getNorthSpawn()); + UtilInv.Clear(player); + + ClansManager.getInstance().getItemMapManager().setMap(player); + }, 20 * 10L); + + player.setWalkSpeed(0.2F); + + //ClansManager.getInstance().getPvpTimer().unpause(player); + + if (!_taskManager.hasCompletedTask(player, getTaskIdentifier())) + { + _taskManager.completedTask(data -> + { + GoldManager.getInstance().addGold(player, 32000); + UtilPlayer.message(player, F.main("Clans", "You have earned " + F.elem(32000 + " Gold") + " for finishing the tutorial!")); + }, player, getTaskIdentifier()); + } + + /* + ClansManager.getInstance().runAsync(() -> + { + _repository.SetTimesPlayed(player.getUniqueId(), _repository.GetTimesPlayed(player.getUniqueId()) + 1); + + final int times = _repository.GetTimesPlayed(player.getUniqueId()); + + if (_repository.GetTimesPlayed(player.getUniqueId()) == 1) + { + ClansManager.getInstance().runSync(() -> + { + if (times == 1) + { + GoldManager.getInstance().addGold(player, 32000); + UtilPlayer.message(player, F.main("Clans", "You have earned " + F.elem(32000 + " Gold") + " for finishing the tutorial!")); + } + + UtilInv.give(player, Material.COOKIE); + }); + } + }); + */ + } + + @Override + protected boolean canStart(Player player) + { + ClanInfo clan = ClansManager.getInstance().getClan(player); + if (clan != null) + { + UtilPlayer.message(player, F.main("Clans", "You are part of a clan - please leave or disband the clan before doing the tutorial")); + return false; + } + return true; + } + + @Override + protected void onStart(Player player) + { + TutorialRegion region = getRegion(player); + + player.teleport(getSpawn(region)); + spawnFences(region, DyeColor.BLACK); // Fields + spawnFences(region, DyeColor.BROWN); // Shops + spawnFences(region, DyeColor.RED); // Middle + + player.setGameMode(GameMode.SURVIVAL); + player.getInventory().clear(); + player.getInventory().setArmorContents(new ItemStack[4]); + player.setHealth(20); + player.setFoodLevel(20); + + //ClansManager.getInstance().getPvpTimer().pause(player); + + // Spawn Holograms + setSpawnHologram(player, + getPoint(region, ClansMainTutorial.Point.SPAWN).add(0, 1.5, -3), + C.cGoldB + "Welcome to the Clans Tutorial!", + " ", + "This will teach you the basics of Clans.", + "It will take about 5 minutes to complete.", + "You must complete it before playing Clans.", + " ", + "Starting in " + C.cGreen + "10 Seconds"); + + player.setWalkSpeed(0); + + addHologram(player, + getPoint(region, ClansMainTutorial.Point.SPAWN).add(0, 1.5, -23), + "Jump Off!"); + } + + @Override + protected void onQuit(Player player) + { + _fireworks.remove(player); + } + + public Location getPoint(TutorialRegion region, Point point) + { + return region.getLocationMap().getGoldLocations(point.getDataLocColor()).get(0).clone(); + } + + public boolean isIn(Location location, TutorialRegion region, Bounds bounds) + { + if (region.getOrigin().getWorld() != location.getWorld()) + return false; + + List locs = region.getLocationMap().getGoldLocations(bounds.getDataLocColor()); + return UtilAlg.inBoundingBox(location, locs.get(0), locs.get(1)); + } + + public boolean isIn(Player player, Bounds bounds) + { + if(player == null || !player.isOnline()) return false; + TutorialRegion region = getRegion(player); + + if (region != null) + { + if (player.getLocation() == null) return false; + return isIn(player.getLocation(), region, bounds); + } + + return false; + } + + public Location getCenter(TutorialRegion region, Bounds bounds) + { + List locs = region.getLocationMap().getGoldLocations(bounds.getDataLocColor()); + return UtilAlg.getMidpoint(locs.get(0), locs.get(1)); + } + + public Location getSpawn(TutorialRegion region) + { + Location location = region.getLocationMap().getGoldLocations(Point.SPAWN.getDataLocColor()).get(0).clone(); + location.setYaw(180); + return location; + } + + public enum Bounds + { + LAND_CLAIM(DyeColor.LIGHT_BLUE), + // Should be 16x16 + ENEMY_LAND(DyeColor.RED), + // Should be 16x16 + SPAWN(DyeColor.GREEN), + // Spawn Platform + FIELDS(DyeColor.PURPLE), + // Boulders for ores to spawn in? + SHOPS(DyeColor.YELLOW), + // Little shop areas similar to Shops in clans map + ENEMY_ATTACK_AREA(DyeColor.BLACK), + NPC_DIE_AREA(DyeColor.BLUE), + NPC_SHOOT_AREA(DyeColor.BROWN); + // Gray Wool - Cannon Location + // Magenta Wool - Spawn + // Lime Wool - Farming Shop + // Purple Wool - Pvp Shop + // Light Gray Wool - Energy Shop + + private DyeColor _dataLocColor; + + Bounds(DyeColor dataLocColor) + { + _dataLocColor = dataLocColor; + } + + public DyeColor getDataLocColor() + { + return _dataLocColor; + } + } + + public enum Point + { + SPAWN(DyeColor.MAGENTA), + FARMING_SHOP(DyeColor.LIME), + PVP_SHOP(DyeColor.PINK), + ENERGY_SHOP(DyeColor.SILVER), + MINING_SHOP(DyeColor.ORANGE), + CANNON(DyeColor.GRAY), + NPC_1(DyeColor.CYAN), + NPC_2(DyeColor.WHITE); + + private DyeColor _dataLocColor; + + Point(DyeColor dataLocColor) + { + _dataLocColor = dataLocColor; + } + + public DyeColor getDataLocColor() + { + return _dataLocColor; + } + } + + @EventHandler + public void dropItem(PlayerDropItemEvent event) + { + if (isInTutorial(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void breakBlock(BlockBreakEvent event) + { + if (isInTutorial(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void blockDamage(EntityDamageEvent event) + { + if (event.getEntity() instanceof Player) + { + if (isInTutorial((Player) event.getEntity())) + event.setCancelled(true); + } + } + + // Fences + // Black = fields + // Brown = shops + public void spawnFence(Block startBlock) + { + Block block = startBlock; + int count = 0; + while ((block.getType() == Material.AIR || block.getType() == Material.FENCE) && count < 100) + { + block.setType(Material.FENCE); + + block = block.getRelative(BlockFace.UP); + count++; + } + } + + public void destroyFence(Block startBlock) + { + Block block = startBlock; + int count = 0; + while (block.getType() == Material.FENCE && count < 100) + { + block.setType(Material.AIR); + + block = block.getRelative(BlockFace.UP); + count++; + } + } + + public void spawnFences(TutorialRegion region, DyeColor dataLoc) + { + List locations = region.getLocationMap().getIronLocations(dataLoc); + locations.stream().map(Location::getBlock).forEach(this::spawnFence); + } + + public void destroyFences(TutorialRegion region, DyeColor dataLoc) + { + List locations = region.getLocationMap().getIronLocations(dataLoc); + locations.stream().map(Location::getBlock).forEach(this::destroyFence); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void teleport(ClansCommandPreExecutedEvent event) + { + if (event.getArguments().length < 1) + { + return; + } + + if (!isInTutorial(event.getPlayer())) + { + return; + } + + if (event.getArguments()[0].equalsIgnoreCase("join") + || event.getArguments()[0].equalsIgnoreCase("leave") + || event.getArguments()[0].equalsIgnoreCase("stuck") + || event.getArguments()[0].equalsIgnoreCase("promote") + || event.getArguments()[0].equalsIgnoreCase("demote") + || event.getArguments()[0].equalsIgnoreCase("invite") + || event.getArguments()[0].equalsIgnoreCase("kick") + || event.getArguments()[0].equalsIgnoreCase("neutral") + || event.getArguments()[0].equalsIgnoreCase("enemy") + || event.getArguments()[0].equalsIgnoreCase("ally") + || event.getArguments()[0].equalsIgnoreCase("trust") + || event.getArguments()[0].equalsIgnoreCase("unclaim") + || event.getArguments()[0].equalsIgnoreCase("claim") + || event.getArguments()[0].equalsIgnoreCase("delete") + || event.getArguments()[0].equalsIgnoreCase("disband") + || event.getArguments()[0].equalsIgnoreCase("admin") + || event.getArguments()[0].equalsIgnoreCase("x")) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You are not allowed to run this command during the Tutorial.")); + event.setCancelled(true); + } + + } + + @EventHandler + public void checkInRegion(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Player player : getPlayers()) + { + if (player == null || !player.isOnline()) continue; + if (player.getLocation().getWorld() != getWorldManager().getTutorialWorld()) + { + TutorialRegion region = getRegion(player); + player.teleport(getSpawn(region)); + } + } + } + + @EventHandler + public void fireworkUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) return; + + for (Player player : _fireworks) + { + if (player == null || !player.isOnline()) continue; + UtilFirework.spawnRandomFirework(UtilAlg.getRandomLocation(player.getLocation(), 10)); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { +// ClansManager.getInstance().runAsync(() -> { +// if (_repository.GetTimesPlayed(event.getPlayer().getUniqueId()) == 0) +// { +// ClansManager.getInstance().runSync(() -> start(event.getPlayer())); +// } +// }); + + /*if (!_taskManager.hasCompletedTask(event.getPlayer(), getTaskIdentifier())) + { + ClanInfo clan = ClansManager.getInstance().getClan(event.getPlayer()); + if (clan == null) + { + start(event.getPlayer()); + } + else + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "It seems you already have a clan here, so we can skip the tutorial")); + } + } + else */if (!event.getPlayer().hasPlayedBefore() || !event.getPlayer().getLocation().getWorld().equals(Spawn.getSpawnWorld())) + { + Spawn.getInstance().teleport(event.getPlayer(), Spawn.getInstance().getSpawnLocation(), 2); + } + } + + @EventHandler + public void preventMovement(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (Player player : getPlayers()) + { + TutorialSession session = getTutorialSession(player); + long time = session.getElapsedTime(); + if (time <= 10000) // 10 seconds + { +// player.teleport(getSpawn(session.getRegion())); + + String secondsLeft = UtilTime.convertString(10000 - time, 0, UtilTime.TimeUnit.SECONDS); + setSpawnHologram(player, + getPoint(session.getRegion(), ClansMainTutorial.Point.SPAWN).add(0, 1.5, -3), + C.cGoldB + "Welcome to the Clans Tutorial!", + " ", + "This will teach you the basics of Clans.", + "It will take about 5 minutes to complete.", + "You must complete it before playing Clans.", + " ", + "Starting in " + C.cGreen + secondsLeft); + } + else if (!session.isRemovedHologram()) + { + removeSpawnHologram(player); + player.setWalkSpeed(0.2F); + } + } + } + + public void performGateCheck(Player player, DyeColor key) + { + if(player == null || !player.isOnline()) return; + Location exact = getRegion(player).getLocationMap().getIronLocations(key).get(0); + if(exact == null) return; + Location fence = UtilAlg.getAverageLocation(getRegion(player).getLocationMap().getIronLocations(key)); + + if (exact.getBlock().getType() == Material.AIR) + { + // Gates are already open. + return; + } + + if (player.getLocation().distanceSquared(fence) <= (GATE_OPEN_DISTANCE * GATE_OPEN_DISTANCE)) + { + // Within the correct blocks of the gates. + destroyFences(getRegion(player), key); + } + } + + public TutorialMapManager getMapManager() + { + return _mapManager; + } + + @EventHandler (priority = EventPriority.LOWEST) + public void onClick(ClansButtonClickEvent event) { + if(isInTutorial(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler (priority = EventPriority.LOWEST) + public void onShop(ClansPlayerBuyItemEvent event) + { + if(isInTutorial(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler (priority = EventPriority.LOWEST) + public void onSell(ClansPlayerSellItemEvent event) + { + if(isInTutorial(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler + public void energyBuy(PreEnergyShopBuyEvent event) + { + if (isInTutorial(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void blockBreak(BlockDamageEvent event) + { + if (!isInTutorial(event.getPlayer())) + { + return; + } + + if (!isInBuildArea(event.getPlayer(), event.getBlock())) + { + return; + } + + + if (_items.contains(event.getBlock().getType())) + { + event.getBlock().breakNaturally(); + + event.getBlock().getWorld().playEffect(event.getBlock().getLocation(), Effect.TILE_BREAK, event.getBlock().getTypeId(), 18); + + event.getPlayer().playSound(event.getBlock().getLocation(), Sound.LAVA_POP, 1.f, 1.f); + } + } + + + + + @EventHandler (priority = EventPriority.HIGHEST) + public void blockPlace(BlockPlaceEvent event) + { + if (!isInTutorial(event.getPlayer())) + { + return; + } + + if (isInBuildArea(event.getPlayer(), event.getBlock())) + { + event.setCancelled(false); + } + else + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You are not allowed to place blocks here.")); + event.setCancelled(true); + } + } + + public boolean isInBuildArea(Player player, Block block) + { + TutorialRegion region = getRegion(player); + return isIn(block.getLocation(), region, ClansMainTutorial.Bounds.LAND_CLAIM); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/AttackEnemyObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/AttackEnemyObjective.java new file mode 100644 index 00000000..705c3cfe --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/AttackEnemyObjective.java @@ -0,0 +1,212 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import mineplex.core.common.DefaultHashMap; +import mineplex.core.common.util.C; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.siege.weapon.Cannon; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.HoldItemGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.BlowUpWallGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.ClanInfoGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.GetMapGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.LoadCannonGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.MountCannonGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.StealEnemyPotatoesGoal; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + +public class AttackEnemyObjective extends OrderedObjective +{ + private Map _cannon; + + private DefaultHashMap> _shooters; + + public AttackEnemyObjective(ClansMainTutorial clansMainTutorial, ClansManager clansManager, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Enemy Clans Tutorial", "Attack and raid this enemy!"); + + _cannon = new HashMap<>(); + _shooters = new DefaultHashMap<>(username -> new ArrayList<>()); + + addGoal(new GetMapGoal(this)); + addGoal(new HoldItemGoal( + this, Material.MAP, + "Identify Enemy on Map", + "Find the Red Square on your Map.", + "Look at your map to help find where the Enemy Clan is. It's marked by " + + "a " + C.cRed + "Red Square" + C.mBody + ".", + 40 + )); + addGoal(new ClanInfoGoal(this)); + addGoal(new MountCannonGoal(this, clansManager)); + addGoal(new LoadCannonGoal(this)); + addGoal(new BlowUpWallGoal(this)); + addGoal(new StealEnemyPotatoesGoal(this)); + + setStartMessageDelay(60); + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getPlugin().getCenter(session.getRegion(), ClansMainTutorial.Bounds.ENEMY_LAND)); + + addShooter("Chiss", getPlugin().getPoint(getPlugin().getRegion(player), ClansMainTutorial.Point.NPC_2), player); + addShooter("defek7", getPlugin().getPoint(getPlugin().getRegion(player), ClansMainTutorial.Point.NPC_1), player); + } + + private void addShooter(String name, Location location, Player active) + { + System.out.println("Adding shooter " + _shooters.get(active.getName()).size() + 1); + + Zombie shooter = location.getWorld().spawn(location.add(.5, 0, .8), Zombie.class); + + shooter.setCustomName(name); + shooter.setCustomNameVisible(true); + + UtilEnt.vegetate(shooter); + + shooter.teleport(location); + shooter.setHealth(shooter.getMaxHealth()); + + shooter.getEquipment().setItemInHand(new ItemStack(Material.BOW, 1)); + shooter.getEquipment().setChestplate(new ItemStack(Material.GOLD_CHESTPLATE, 1)); + shooter.getEquipment().setBoots(new ItemStack(Material.GOLD_BOOTS, 1)); + shooter.getEquipment().setHelmet(new ItemStack(Material.GOLD_HELMET, 1)); + + _shooters.get(active.getName()).add(shooter); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.FASTER) + { + for (Player player : getActivePlayers()) + { + _shooters.get(player.getName()).forEach(shooter -> { + shooter.setHealth(shooter.getMaxHealth()); + + shooter.getEquipment().setItemInHand(new ItemStack(Material.BOW, 1)); + shooter.getEquipment().setChestplate(new ItemStack(Material.GOLD_CHESTPLATE, 1)); + shooter.getEquipment().setBoots(new ItemStack(Material.GOLD_BOOTS, 1)); + shooter.getEquipment().setHelmet(new ItemStack(Material.GOLD_HELMET, 1)); + + if (player.getLocation().distance(shooter.getLocation()) > 16) + { + return; + } + + UtilEnt.LookAt(shooter, player.getEyeLocation()); + + if (Recharge.Instance.usable(player, "ShotBy" + shooter.getUniqueId().toString())) + { + Arrow arrow = shooter.shootArrow(); + + arrow.setVelocity(UtilAlg.getTrajectory(arrow.getLocation(), player.getEyeLocation()).multiply(1.6)); + + Recharge.Instance.use(player, "ShotBy" + shooter.getUniqueId().toString(), 500 + UtilMath.r(2000), false, false); + } + }); + + EnclosedObject kill = new EnclosedObject<>(Boolean.FALSE); + + _shooters.get(player.getName()).forEach(shooter -> + { + if (player.getLocation().distance(shooter.getLocation()) < 5) + { + kill.Set(Boolean.TRUE); + } + }); + + if (kill.Get()) + { + _shooters.get(player.getName()).forEach(shooter -> { + UtilParticle.PlayParticle(ParticleType.LARGE_SMOKE, shooter.getLocation().add(0, .5, 0), new Vector(0d, 0d, 0d), 0.2f, 15, ViewDist.MAX, player); + UtilParticle.PlayParticle(ParticleType.SMOKE, shooter.getLocation().add(0, .5, 0), new Vector(0d, 0d, 0d), 0.2f, 15, ViewDist.MAX, player); + player.playSound(player.getLocation(), Sound.LAVA_POP, 1.0f, 1.0f); + shooter.remove(); + }); + + _shooters.get(player.getName()).clear(); + } + + if (player.getHealth() <= 6) + { + player.setHealth(6); + } + } + } + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + public void clean(Player player, TutorialRegion region) + { + super.clean(player, region); + + System.out.println("Clearing shooters"); + + _shooters.get(player.getName()).forEach(shooter -> { + shooter.remove(); + }); + + _shooters.get(player.getName()).clear(); + } + + @Override + protected void customFinish(Player player) + { + System.out.println("Clearing shooters"); + + _shooters.get(player.getName()).forEach(shooter -> { + shooter.remove(); + }); + + _shooters.get(player.getName()).clear(); + } + + public Map getCannons() + { + return _cannon; + } + + public DefaultHashMap> getShooters() + { + return _shooters; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ClanObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ClanObjective.java new file mode 100644 index 00000000..2374ae9b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ClanObjective.java @@ -0,0 +1,39 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan.*; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.BlowUpWallGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy.StealEnemyPotatoesGoal; + +public class ClanObjective extends OrderedObjective +{ + public ClanObjective(ClansMainTutorial clansMainTutorial, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Clans Tutorial", "Create clan with /c create "); + + addGoal(new LeaveSpawnGoal(this)); + addGoal(new CreateClanGoal(this)); + addGoal(new ClanManagementGoal(this)); + addGoal(new ClaimLandGoal(this)); + addGoal(new BuildHouseGoal(this)); + addGoal(new SetHomeGoal(this)); + + // Wait 1 second because the player is logging in/loading + setStartMessageDelay(20); + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ClassesObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ClassesObjective.java new file mode 100644 index 00000000..67159694 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ClassesObjective.java @@ -0,0 +1,44 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes.EquipDefaultBuildGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes.OpenClassManagerGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes.UseBullsChargeGoal; + +public class ClassesObjective extends OrderedObjective +{ + public ClassesObjective(ClansMainTutorial clansMainTutorial, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Classes Tutorial", "Learn to use our fully customizable classes"); + + addGoal(new EquipDefaultBuildGoal(this)); + addGoal(new OpenClassManagerGoal(this)); + addGoal(new UseBullsChargeGoal(this)); + + setStartMessageDelay(60); + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(null); + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/EnergyObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/EnergyObjective.java new file mode 100644 index 00000000..ecced2ab --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/EnergyObjective.java @@ -0,0 +1,42 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.energy.BuyEnergyGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.energy.ExplainEnergyGoal; + +public class EnergyObjective extends OrderedObjective +{ + public EnergyObjective(ClansMainTutorial clansMainTutorial, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Energy Tutorial", "A Clan requires Energy to maintain all of it's territory."); + + addGoal(new ExplainEnergyGoal(this)); + addGoal(new BuyEnergyGoal(this)); + + setStartMessageDelay(60); + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getPlugin().getPoint(session.getRegion(), ClansMainTutorial.Point.ENERGY_SHOP)); + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/FieldsObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/FieldsObjective.java new file mode 100644 index 00000000..7ff835cc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/FieldsObjective.java @@ -0,0 +1,56 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.C; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.HoldItemGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields.GoToFieldsGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields.MineDiamondsGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields.SellDiamondsGoal; + +public class FieldsObjective extends OrderedObjective +{ + public FieldsObjective(ClansMainTutorial clansMainTutorial, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Fields Tutorial", "Get various resources by mining for them in the fields"); + + addGoal(new HoldItemGoal( + this, + Material.MAP, + "Identify Fields on Map", + "Find the Orange Striped Area on your Map", + "Fields are marked by " + C.cGold + "Orange Stripes" + C.mBody + ".", + 80L + )); + addGoal(new GoToFieldsGoal(this)); + addGoal(new MineDiamondsGoal(this)); + addGoal(new SellDiamondsGoal(this)); + +// setStartMessageDelay(60); + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getPlugin().getCenter(session.getRegion(), ClansMainTutorial.Bounds.FIELDS)); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/FinalObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/FinalObjective.java new file mode 100644 index 00000000..9ea92b62 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/FinalObjective.java @@ -0,0 +1,42 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.finalobj.DisbandClanGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.finalobj.TpClanHomeGoal; + +public class FinalObjective extends OrderedObjective +{ + public FinalObjective(ClansMainTutorial clansMainTutorial, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Clans Tutorial 2", "Finalize your knowledge of Clans"); + + addGoal(new TpClanHomeGoal(this)); // IMPLEMENTED + addGoal(new DisbandClanGoal(this)); // IMPLEMENTED + + setStartMessageDelay(60); + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(null); + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/PurchaseItemsObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/PurchaseItemsObjective.java new file mode 100644 index 00000000..b86ab328 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/PurchaseItemsObjective.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import org.bukkit.*; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.UnorderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.shops.PurchaseGoal; + +import java.util.List; +import java.util.UUID; + +public class PurchaseItemsObjective extends UnorderedObjective +{ + public PurchaseItemsObjective(ClansMainTutorial clansMainTutorial, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Purchase Items Tutorial", "Purchase Items from Shop"); + + addGoal(new PurchaseGoal( + this, + Material.IRON_HELMET, + "Purchase Iron Helmet", + "Buy an Iron Helmet from the PvP Gear NPC", + "The shops sell everything you could ever need and more. Buy armour from the " + C.cYellow + "PvP NPC." + )); + addGoal(new PurchaseGoal(this, Material.IRON_CHESTPLATE, "Purchase Iron Chestplate", + "Buy an Iron Chestplate")); + addGoal(new PurchaseGoal(this, Material.IRON_LEGGINGS, "Purchase Iron Leggings", + "Buy Iron Leggings")); + addGoal(new PurchaseGoal(this, Material.IRON_BOOTS, "Purchase Iron Boots", + "Buy Iron Boots")); + addGoal(new PurchaseGoal(this, Material.IRON_AXE, "Purchase Iron Axe", + "Buy an Iron Axe")); +// addGoal(new PurchaseGoal(this, Material.IRON_PICKAXE, "Purchase Iron Pickaxe", "Talk to the Pvp Gear NPC and purchase an Iron Pickaxe")); + + setStartMessageDelay(60); + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getPlugin().getPoint(session.getRegion(), ClansMainTutorial.Point.PVP_SHOP)); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void update(UpdateEvent event) { + if(!event.getType().equals(UpdateType.SEC_05)) return; + + for (Player player : getActivePlayers()) + { + if (player == null || !player.isOnline()) continue; + List locations = getPlugin().getRegion(player).getLocationMap().getSpongeLocations(DyeColor.BROWN); + if (locations == null) continue; + for(Location loc : locations) + { + UtilFirework.playFirework(loc, FireworkEffect.Type.BURST, Color.AQUA, true, true); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ShopsObjective.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ShopsObjective.java new file mode 100644 index 00000000..84090b45 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/ShopsObjective.java @@ -0,0 +1,119 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.npc.Npc; +import mineplex.core.npc.NpcManager; +import mineplex.database.tables.records.NpcsRecord; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.OrderedObjective; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.HoldItemGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.shops.GoToShopsGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.goals.shops.SellPotatoesGoal; + +public class ShopsObjective extends OrderedObjective +{ + private HashMap> _npcMap; + private NpcManager _npcManager; + + public ShopsObjective(ClansMainTutorial clansMainTutorial, NpcManager npcManager, JavaPlugin javaPlugin) + { + super(clansMainTutorial, javaPlugin, "Shops Tutorial", "Learn your way around our shops"); + + _npcMap = new HashMap<>(); + _npcManager = npcManager; + + addGoal(new HoldItemGoal( + this, + Material.MAP, + "Identify Shops on Map", + "Find the Blue Striped Area on your map", + "Shops are marked on the map by the " + C.cDAqua + "Blue Stripes" + C.mBody + ".", + 60L + )); + addGoal(new GoToShopsGoal(this)); + addGoal(new SellPotatoesGoal(this)); + + setStartMessageDelay(60); + } + + @Override + public void clean(Player player, TutorialRegion region) + { + super.clean(player, region); + + if (_npcMap.containsKey(player.getUniqueId())) + { + _npcMap.get(player.getUniqueId()).forEach(npc -> _npcManager.removeFakeNpc(npc)); + } + } + + @Override + protected void customLeave(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @Override + protected void customStart(Player player) + { + super.customStart(player); + + TutorialRegion region = getPlugin().getRegion(player); + + + ArrayList npcs = new ArrayList<>(); + // Spawn NPC's + Location pvpGear = getPlugin().getPoint(region, ClansMainTutorial.Point.PVP_SHOP); + Location energyShop = getPlugin().getPoint(region, ClansMainTutorial.Point.ENERGY_SHOP); + Location farmingShop = getPlugin().getPoint(region, ClansMainTutorial.Point.FARMING_SHOP); + Location miningShop = getPlugin().getPoint(region, ClansMainTutorial.Point.MINING_SHOP); + npcs.add(spawnNpc(pvpGear, "Pvp Gear")); + npcs.add(spawnNpc(energyShop, "Energy Shop")); + npcs.add(spawnNpc(farmingShop, "Organic Produce")); + npcs.add(spawnNpc(miningShop, "Mining Shop")); + _npcMap.put(player.getUniqueId(), npcs); + + TutorialSession session = getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getPlugin().getCenter(session.getRegion(), ClansMainTutorial.Bounds.SHOPS)); + + } + + private Npc spawnNpc(Location location, String name) + { + NpcsRecord npcsRecord = new NpcsRecord(); + npcsRecord.setServer(_npcManager.getServerName()); + npcsRecord.setName(name); + npcsRecord.setWorld(location.getWorld().getName()); + npcsRecord.setX(location.getX()); + npcsRecord.setY(location.getY()); + npcsRecord.setZ(location.getZ()); + npcsRecord.setRadius(0D); + npcsRecord.setEntityType(EntityType.VILLAGER.name()); + npcsRecord.setAdult(true); + + Npc npc = new Npc(_npcManager, npcsRecord); + _npcManager.spawnNpc(npc); + _npcManager.addFakeNpc(npc); + return npc; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/HoldItemGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/HoldItemGoal.java new file mode 100644 index 00000000..2f504a8a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/HoldItemGoal.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.DefaultHashMap; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.objective.Objective; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; + +public class HoldItemGoal extends ObjectiveGoal> +{ + private DefaultHashMap> _ticksHeld = new DefaultHashMap<>(key -> new EnclosedObject<>(0)); + private Material _material; + private long _holdTicks; + + public HoldItemGoal(Objective objective, Material material, String name, String description, String helpText, int startDelay, long holdTicks) + { + super(objective, name, description, helpText, null); + + _material = material; + _holdTicks = holdTicks; +// setStartMessageDelay(startDelay); + } + + public HoldItemGoal(Objective objective, Material material, String name, String description, String helpText, long holdTicks) + { + this(objective, material, name, description, helpText, 120, holdTicks); + } + + @Override + protected void customStart(Player player) + { + + } + + @Override + protected void customFinish(Player player) + { + _ticksHeld.remove(player.getName()); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + getActivePlayers().forEach(uuid -> + { + Player player = Bukkit.getPlayer(uuid); + + if (player != null && player.isOnline()) + { + if (player.getItemInHand() == null || player.getItemInHand().getType() != _material) + { + return; + } + + _ticksHeld.get(player.getName()).Set(_ticksHeld.get(player.getName()).Get() + 1); + + if (_ticksHeld.get(player.getName()).Get() >= 80) + { + finish(player); + } + } + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/BlowUpWallGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/BlowUpWallGoal.java new file mode 100644 index 00000000..756c26a4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/BlowUpWallGoal.java @@ -0,0 +1,116 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.fallingblock.FallingBlocks; +import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; + +public class BlowUpWallGoal extends ObjectiveGoal +{ + public BlowUpWallGoal(AttackEnemyObjective objective) + { + super( + objective, + "Blow up the Enemy Base", + "Left-Click to shoot TNT at the Enemy Base", + "TNT Cannons will rotate to the direction you are looking. Simply look at the Enemy Base, wait for it to rotate, and then FIRE!", + DyeColor.MAGENTA + ); + } + + @Override + protected void customStart(Player player) + { + TutorialSession session = getObjective().getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getObjective().getPlugin().getCenter(session.getRegion(), ClansMainTutorial.Bounds.ENEMY_ATTACK_AREA)); + } + + @EventHandler + public void siegeWeaponExplode(SiegeWeaponExplodeEvent event) + { + Player shooter = event.getProjectile().getShooter(); + + if (!contains(shooter)) + { + if (getObjective().getPlugin().isInTutorial(shooter)) + { + UtilPlayer.message(shooter, F.main("Clans", "No cheating! (:")); + event.setCancelled(true); + } + + return; + } + + Location center = event.getProjectile().getLocation(); + + TutorialRegion region = getObjective().getPlugin().getRegion(shooter); + + double radius = 5.2; + + Map blockList = new HashMap<>(); + int iR = (int) radius + 1; + + for (int x = -iR; x <= iR; x++) + { + for (int z = -iR; z <= iR; z++) + { + for (int y = -iR; y <= iR; y++) + { + Block curBlock = center.getBlock().getRelative(x, y, z); + + double offset = UtilMath.offset(center, curBlock.getLocation()); + + if (offset <= radius) + { + blockList.put(curBlock, Double.valueOf(offset)); + } + } + } + } + + blockList.forEach((block, dist) -> { + + if (block.getType() == Material.SMOOTH_BRICK + || block.getType() == Material.SMOOTH_STAIRS + || block.getType() == Material.IRON_DOOR_BLOCK) + + if (Math.random() < 0.2 + (dist / 2.55) || dist < 1.75) + { + block.setType(Material.AIR, false); + + if (block.getType() != Material.IRON_DOOR_BLOCK && block.getType().name().endsWith("BANNER")) + FallingBlocks.Instance.Spawn(block.getLocation(), block.getType(), block.getData(), center); + } + }); + + event.setCancelled(true); + finish(shooter); + } + + @Override + protected void customFinish(Player player) + { + getObjective().getCannons().remove(player.getName()).kill(); //Kill cannon after goal complete + + getObjective().getShooters().get(player.getName()).forEach(Zombie::remove); + + getObjective().getShooters().get(player.getName()).clear(); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/ClanInfoGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/ClanInfoGoal.java new file mode 100644 index 00000000..f240f5c2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/ClanInfoGoal.java @@ -0,0 +1,92 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; + + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansPlayer; +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.core.repository.tokens.ClanToken; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import java.sql.Timestamp; +import java.util.UUID; + + +public class ClanInfoGoal extends ObjectiveGoal +{ + public ClanInfoGoal(AttackEnemyObjective objective) + { + super( + objective, + "Lookup Enemy Details", + "View info about the enemy clan by typing '/c EnemyClan'", + "You can lookup details about your enemy before going for an " + + "attack! This can give you a crucial advantage before " + + "you fight.", + null + ); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onClanInfo(ClansCommandPreExecutedEvent event) + { + if (contains(event.getPlayer())) + { + if(event.getArguments().length < 1) return; + + event.setCancelled(true); + + if (!event.getArguments()[0].equalsIgnoreCase("EnemyClan")) + { + event.getPlayer().sendMessage(F.main("Clans", "That clan does not exist.")); + return; + } + + ClanToken token = new ClanToken(); + token.Name = "EnemyClan"; + token.Description = "Chiss"; + token.Home = ""; + token.Admin = false; + token.Energy = 4320; + token.Id = -1; + token.Kills = UtilMath.random.nextInt(100); + token.Murder = UtilMath.random.nextInt(100); + token.Deaths = UtilMath.random.nextInt(100); + token.WarWins = UtilMath.random.nextInt(100); + token.WarLosses = UtilMath.random.nextInt(100); + token.DateCreated = new Timestamp(System.currentTimeMillis() - (UtilTime.TimeUnit.DAYS.getMilliseconds() * 10)); + token.LastOnline = new Timestamp(System.currentTimeMillis() - (UtilTime.TimeUnit.DAYS.getMilliseconds() * 1)); + + ClanInfo clan = new ClanInfo(ClansManager.getInstance(), token); + + ClansPlayer chiss = new ClansPlayer("Chiss", UUID.fromString("1d2bfe61-7ebd-445d-ba7d-8354a0ffd1ea"), ClanRole.LEADER); + ClansPlayer jon = new ClansPlayer("defek7", UUID.fromString("89d463f7-23ec-470a-8244-457f0c8d861c"), ClanRole.MEMBER); + chiss.setOnline(true); + jon.setOnline(true); + + clan.getMembers().put(chiss.getUuid(), chiss); + clan.getMembers().put(jon.getUuid(), jon); + + ClansManager.getInstance().getClanShop().openClanWho(event.getPlayer(), clan); + finish(event.getPlayer()); + + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/GetMapGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/GetMapGoal.java new file mode 100644 index 00000000..c1301087 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/GetMapGoal.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.C; +import mineplex.game.clans.clans.map.events.PlayerGetMapEvent; +import mineplex.game.clans.clans.siege.weapon.Cannon; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; + +public class GetMapGoal extends ObjectiveGoal +{ + public GetMapGoal(AttackEnemyObjective objective) + { + super( + objective, + "Get a Map", + "Type '/map' to get a Map", + "You can get a Map any time you need one. The map will show you who " + + "owns the land around the map. Your clan is " + C.cAqua + "blue" + + C.mBody + ", your allies are " + C.cGreen + "green" + C.mBody + ", " + + "and your enemies are " + C.cRed + "red" + C.mBody + ".", + null + ); + +// setStartMessageDelay(120); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onGetMap(PlayerGetMapEvent event) + { + if (getObjective().getPlugin().isInTutorial(event.getPlayer())) + { + event.setCancelled(true); + getObjective().getPlugin().getMapManager().setMap(event.getPlayer()); + + if (contains(event.getPlayer())) + { + finish(event.getPlayer()); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/LoadCannonGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/LoadCannonGoal.java new file mode 100644 index 00000000..21b69d37 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/LoadCannonGoal.java @@ -0,0 +1,61 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.UtilInv; +import mineplex.game.clans.clans.siege.events.LoadSiegeWeaponEvent; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; + +public class LoadCannonGoal extends ObjectiveGoal +{ + public LoadCannonGoal(AttackEnemyObjective objective) + { + super( + objective, + "Load the Cannon", + "Right-Click while on the Cannon, and insert your TNT", + "TNT Cannons require TNT to be able to shoot. You can also change the range your cannon fires in the Cannon Menu.", + null + ); + } + + @Override + protected void customStart(Player player) + { + UtilInv.give(player, Material.TNT); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onSiegeWeaponLoad(LoadSiegeWeaponEvent event) + { + if (!contains(event.getPlayer())) + { + return; + } + + finish(event.getPlayer()); + } + + @EventHandler (priority = EventPriority.MONITOR) + public void onBlockPlace(BlockPlaceEvent event) + { + if (!contains(event.getPlayer())) + { + return; + } + UtilPlayer.message(event.getPlayer(), F.main("Clans", "Are you sure? That's the only TNT you have!")); + event.setCancelled(true); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/MountCannonGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/MountCannonGoal.java new file mode 100644 index 00000000..8db5dfbf --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/MountCannonGoal.java @@ -0,0 +1,72 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; + +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.siege.events.MountSiegeWeaponEvent; +import mineplex.game.clans.clans.siege.weapon.Cannon; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial.Point; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; + +import org.bukkit.DyeColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +public class MountCannonGoal extends ObjectiveGoal +{ + private ClansManager _clansManager; + + public MountCannonGoal(AttackEnemyObjective objective, ClansManager clansManager) + { + super( + objective, + "Get on the Cannon", + "Right-Click on the Cannon", + "You cannot break blocks in enemy territory, however you can blow them up! " + + "TNT Cannons are the best way to do destroy enemy bases!", + DyeColor.BLACK + ); + + _clansManager = clansManager; + } + + @Override + protected void customStart(Player player) + { + getObjective().getCannons().put(player.getName(), _clansManager.getSiegeManager().spawnCannon(player, getObjective().getPlugin().getPoint(getObjective().getPlugin().getRegion(player), Point.CANNON), false)); + getObjective().getCannons().get(player.getName()).SetForcedVelocity(0.44, 2.45); + getObjective().getCannons().get(player.getName()).setInvincible(true); + + getObjective().getCannons().get(player.getName()).LockYaw(-193, -173); + + TutorialSession session = getObjective().getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getObjective().getPlugin().getPoint(session.getRegion(), ClansMainTutorial.Point.CANNON)); + } + + @Override + protected void clean(Player player, TutorialRegion region) + { + // This cannon could be removed from the tutorial already in BlowUpWallGoal, we need to check if its null + Cannon cannon = getObjective().getCannons().remove(player.getName()); + if (cannon != null) + cannon.kill(); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onSiegeWeaponMount(MountSiegeWeaponEvent event) + { + if (!contains(event.getPlayer())) + { + return; + } + + finish(event.getPlayer()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/StealEnemyPotatoesGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/StealEnemyPotatoesGoal.java new file mode 100644 index 00000000..1f426156 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/attackenemy/StealEnemyPotatoesGoal.java @@ -0,0 +1,129 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy; + +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +import mineplex.core.common.util.UtilBlock; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.entity.EntityInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.DefaultHashMap; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective; + +public class StealEnemyPotatoesGoal extends ObjectiveGoal +{ + private DefaultHashMap _playersMap = new DefaultHashMap<>(uuid -> new AtomicInteger()); + + public StealEnemyPotatoesGoal(AttackEnemyObjective objective) + { + super( + objective, + "Steal Potatoes", + "Steal potatoes from the Enemy Clan’s base", + "Raiding enemy bases is one of the best parts of Clans! There's nothing better than looting Legendary weapons from enemies!", + DyeColor.PURPLE + ); + } + + @Override + public String getDescription(Player player) + { + int count = _playersMap.get(player.getUniqueId()).get(); + return "Steal potatoes from the Enemy Clan’s base " + count + "/10"; + } + + @Override + protected void customStart(Player player) + { + _playersMap.put(player.getUniqueId(), new AtomicInteger(0)); + + TutorialSession session = getObjective().getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getObjective().getPlugin().getCenter(session.getRegion(), ClansMainTutorial.Bounds.ENEMY_LAND)); + + UtilBlock.getInRadius( + getObjective().getPlugin().getRegion(player).getLocationMap().getSpongeLocations(DyeColor.MAGENTA).get(0), 5). + keySet().stream().filter(block -> block.getType().name().contains("IRON_DOOR")).forEach(block -> + block.setType(Material.AIR) + ); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onEntityInteract(EntityInteractEvent event) + { + if (!(event.getEntity() instanceof Player)) + { + return; + } + + if (!getObjective().getPlugin().isInTutorial((Player) event.getEntity())) + { + return; + } + + if (event.getBlock().getType() == Material.SOIL && event.getEntity() instanceof Creature) + { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockBreak(BlockDamageEvent event) + { + if (!contains(event.getPlayer()) || event.getBlock().getType() != Material.POTATO) + return; + + TutorialRegion region = getObjective().getPlugin().getRegion(event.getPlayer()); + if (getObjective().getPlugin().isIn(event.getBlock().getLocation().add(0, 1, 0), region, ClansMainTutorial.Bounds.ENEMY_LAND)) + { + event.setCancelled(true); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation().add(0.5, 0.5, 0.5), new ItemStack(Material.POTATO_ITEM)); + event.getBlock().setType(Material.AIR); + + Bukkit.getServer().getScheduler().runTaskLater(getObjective().getJavaPlugin(), new Runnable() + { + @Override + public void run() + { + if (contains(event.getPlayer())) + { + event.getBlock().setType(Material.POTATO); + } + } + }, 20 * 10); + } + } + + @EventHandler + public void onItemPickup(PlayerPickupItemEvent event) + { + if (!contains(event.getPlayer())) + return; + + if (event.getItem().getItemStack().getType() == Material.POTATO_ITEM) + { + int count = _playersMap.get(event.getPlayer().getUniqueId()).incrementAndGet(); + if (count == 10) + finish(event.getPlayer()); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/BuildHouseGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/BuildHouseGoal.java new file mode 100644 index 00000000..4c26307c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/BuildHouseGoal.java @@ -0,0 +1,94 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import java.util.List; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + +import com.google.common.collect.Lists; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; + +public class BuildHouseGoal extends ObjectiveGoal +{ + private List _items = Lists.newArrayList( + new ItemStack(Material.SMOOTH_BRICK, 54), + new ItemStack(Material.TORCH, 2), + new ItemStack(Material.IRON_DOOR, 1) + ); + + + public BuildHouseGoal(ClanObjective objective) + { + super( + objective, + "Build a House", + "Build a House (place all your blocks)", + "The first thing you should do on your land is build a house, even " + + "if it’s made of dirt! This will give you a safe place to store your loot!", + DyeColor.ORANGE + ); + } + + @Override + protected void customStart(Player player) + { + _items.forEach(item -> { + player.getInventory().addItem(item); + }); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler (priority = EventPriority.HIGHEST) + public void blockPlace(BlockPlaceEvent event) + { + if (!getObjective().getPlugin().isInTutorial(event.getPlayer())) + { + return; + } + + event.setCancelled(false); + + + if (getObjective().getPlugin().isInBuildArea(event.getPlayer(), event.getBlock())) + { + // Run 1 tick later because inventory doesn't get updated instantly + ClansManager.getInstance().runSync(() -> { + boolean ja = true; + for (ItemStack stack : event.getPlayer().getInventory().getContents()) + { + if (stack == null) + continue; + + for (ItemStack other : _items) + if (stack.getType() == other.getType()) + { + ja = false; + break; + } + } + + if (ja) // JA! + finish(event.getPlayer()); + }); + } + else + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You are not allowed to place blocks here.")); + event.setCancelled(true); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClaimLandGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClaimLandGoal.java new file mode 100644 index 00000000..93d82a08 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClaimLandGoal.java @@ -0,0 +1,76 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import java.util.List; + +import mineplex.core.common.util.C; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.event.PlayerPreClaimTerritoryEvent; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; +import org.bukkit.event.EventPriority; + +public class ClaimLandGoal extends ObjectiveGoal +{ + public ClaimLandGoal(ClanObjective objective) + { + super( + objective, + "Claim Land", + "Type '/c' to Claim Land using the Clan Menu", + "Clans are able to claim land for themselves. " + + "Once claimed, no one else can break or place blocks there! " + + "You must be inside the " + C.cAqua + "blue" + C.cGray + " outline to claim land.", + DyeColor.ORANGE + ); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + TutorialRegion region = getObjective().getPlugin().getRegion(player); + List blocks = region.getLocationMap().getGoldLocations(ClansMainTutorial.Bounds.LAND_CLAIM.getDataLocColor()); + UtilAlg.getBox(blocks.get(0).getBlock(), blocks.get(1).getBlock()).stream().filter(block -> block.getType() == Material.WOOL) + .forEach(block -> block.setType(Material.GLOWSTONE)); + } + + @EventHandler + public void onClaim(PlayerPreClaimTerritoryEvent event) + { + if (contains(event.getClaimer())) + { + if (getObjective().getPlugin().isIn(event.getClaimer(), ClansMainTutorial.Bounds.LAND_CLAIM)) + { + finish(event.getClaimer()); + } + else + { + UtilPlayer.message(event.getClaimer(), F.main("Tutorial", "You must claim the land inside the blue outline")); + } + + event.setCancelled(true); + } + } + + + @EventHandler (priority = EventPriority.HIGHEST) + public void onClick(ClansButtonClickEvent event) { + if(contains(event.getPlayer()) && event.getButtonType().equals(ClansButtonClickEvent.ButtonType.Territory)) + event.setCancelled(false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClanDetailsGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClanDetailsGoal.java new file mode 100644 index 00000000..fed068dd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClanDetailsGoal.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; +import org.bukkit.event.EventPriority; + +public class ClanDetailsGoal extends ObjectiveGoal +{ + public ClanDetailsGoal(ClanObjective objective) + { + super(objective, "View Clan Details", "View Clan Details with /c"); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @Override + public String getDescription(Player player) + { + ClanInfo clan = ClansManager.getInstance().getClan(player); + if (clan != null) + { + return "View Clan Details with /c " + clan.getName(); + } + else + { + return "View Clan Details"; + } + } + + @EventHandler + public void onClanInfo(ClansCommandExecutedEvent event) + { + if (contains(event.getPlayer())) + { + if (event.getCommand().equalsIgnoreCase("info")) + { + finish(event.getPlayer()); + } + } + } + + + @EventHandler (priority = EventPriority.HIGHEST) + public void onClick(ClansButtonClickEvent event) { + if(contains(event.getPlayer()) && (event.getButtonType().equals(ClansButtonClickEvent.ButtonType.Who))) + event.setCancelled(false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClanManagementGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClanManagementGoal.java new file mode 100644 index 00000000..b74e7d67 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/ClanManagementGoal.java @@ -0,0 +1,60 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import mineplex.core.common.util.F; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; + +/** + * Created by Adam on 29/03/2016. + */ +public class ClanManagementGoal extends ObjectiveGoal +{ + public ClanManagementGoal(ClanObjective objective) + { + super( + objective, + "Open the Clan Menu", + "Type '/c' to open the Clan Menu", + "Clan Menu lets you do lots of Clans actions, and view information about your Clan. Take a moment to look at it all!", + null + ); + } + + @Override + protected void customStart(Player player) + { + player.sendMessage(F.main("Clans", "You can use the command /c to manage your clan.")); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onClanInfo(ClansCommandPreExecutedEvent event) + { + if (contains(event.getPlayer())) + { + if (event.getArguments() == null || event.getArguments().length == 0) + { + finish(event.getPlayer()); + } + } + } + + + @EventHandler (priority = EventPriority.HIGHEST) + public void onClick(ClansButtonClickEvent event) { + if(contains(event.getPlayer()) && event.getButtonType().equals(ClansButtonClickEvent.ButtonType.Energy)) + event.setCancelled(false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/CreateClanGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/CreateClanGoal.java new file mode 100644 index 00000000..d44f6386 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/CreateClanGoal.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import mineplex.core.common.util.F; +import mineplex.game.clans.clans.event.ClanCreatedEvent; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClanCreationCompleteEvent; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; +import org.bukkit.event.EventPriority; + +public class CreateClanGoal extends ObjectiveGoal +{ + public CreateClanGoal(ClanObjective objective) + { + super( + objective, + "Create a Clan", + "Type '/c create ' to create a new Clan", + F.elem("Clans") + " are groups of players that can claim land, build fortresses, " + + "and fight epic battles. Together they will challenge other clans for " + + "control of the land.", + null + ); + } + + @Override + protected void customStart(Player player) + { + + if (ClansManager.getInstance().getClan(player) != null) + { + finish(player); + } + } + + @Override + protected void customFinish(Player player) + { + + } + + @EventHandler + public void onClanCreate(ClanCreationCompleteEvent event) + { + if (contains(event.getFounder())) + { + finish(event.getFounder()); + ClansManager.getInstance().resetLeftTimer(event.getFounder().getUniqueId()); + } + } + + + @EventHandler (priority = EventPriority.HIGHEST) + public void onClick(ClansButtonClickEvent event) { + if(contains(event.getPlayer()) && event.getButtonType().equals(ClansButtonClickEvent.ButtonType.Create)) + event.setCancelled(false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/LeaveSpawnGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/LeaveSpawnGoal.java new file mode 100644 index 00000000..3de4a667 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/LeaveSpawnGoal.java @@ -0,0 +1,79 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import java.util.HashSet; +import java.util.UUID; + +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; + +public class LeaveSpawnGoal extends ObjectiveGoal +{ + public LeaveSpawnGoal(ClanObjective objective) + { + super( + objective, + "Leave Spawn Island", + "Jump off Spawn Island", + F.elem("Spawn Island") + " is where you will respawn when you die. This area is " + + "a " + F.elem("Safe Zone") + ", meaning that players cannot hurt each other. " + + "From here, you can teleport to various places, as well as read some helpful " + + "hints.", + DyeColor.WHITE + ); + + // 2 seconds after start message + setStartMessageDelay(20 * 11); + } + + @Override + protected void setup(Player player, TutorialRegion region) + { + + } + + @Override + protected void customStart(Player player) + { + player.getInventory().clear(); + } + + @Override + protected void customFinish(Player player) + { + + } + + @EventHandler + public void onCommand(ClansCommandPreExecutedEvent event) + { + if(contains(event.getPlayer())) event.setCancelled(true); + } + + @EventHandler + public void checkRegion(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (UUID uuid : getActivePlayers()) + { + Player player = Bukkit.getPlayer(uuid); + if(player == null || !player.isOnline()) continue; + if (!getObjective().getPlugin().isIn(player, ClansMainTutorial.Bounds.SPAWN)) + { + finish(Bukkit.getPlayer(uuid)); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/SetHomeGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/SetHomeGoal.java new file mode 100644 index 00000000..d8a8042f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/clan/SetHomeGoal.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.clan; + +import mineplex.core.common.util.UtilBlock; +import net.minecraft.server.v1_8_R3.EnumDirection; +import org.bukkit.DyeColor; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilWorld; +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClanObjective; + +public class SetHomeGoal extends ObjectiveGoal +{ + public SetHomeGoal(ClanObjective objective) + { + super( + objective, + "Set Clan Home", + "Type '/c sethome' to set your Clan's Home", + "Your Clan Home is a special place in your base that you can teleport " + + "to from " + F.elem("Spawn Island") + " or at any time by typing " + F.elem("/c home") + ".", + DyeColor.ORANGE + ); + + setDisplayFinishMessage(false); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onSetHome(ClansCommandPreExecutedEvent event) + { + if (contains(event.getPlayer()) && event.getArguments().length == 1 && event.getArguments()[0].equalsIgnoreCase("sethome")) + { + event.setCancelled(true); //before checking if bed placed + + if (getObjective().getPlugin().isIn(event.getPlayer(), ClansMainTutorial.Bounds.LAND_CLAIM)) + { + boolean bedPlaced = UtilBlock.placeBed(event.getPlayer().getLocation(), BlockFace.valueOf(EnumDirection.fromAngle(event.getPlayer().getLocation().getYaw()).name()), false, false); + + if (!bedPlaced) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "This is not a suitable place for a bed.")); + return; + } + + // we need to save this for later when the player teleports home! + getObjective().getPlugin().getTutorialSession(event.getPlayer()).setHomeLocation(event.getPlayer().getLocation()); + + finish(event.getPlayer()); + + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have successfully set your Clan's Home to " + UtilWorld.locToStrClean(event.getPlayer().getLocation()) + ".")); + } + else + { + UtilPlayer.message(event.getPlayer(), F.main("Tutorial", "You must set your home in your own land claim.")); + } + + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/EquipDefaultBuildGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/EquipDefaultBuildGoal.java new file mode 100644 index 00000000..9eb963c4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/EquipDefaultBuildGoal.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClassesObjective; +import mineplex.minecraft.game.classcombat.Class.event.ClassEquipEvent; + +public class EquipDefaultBuildGoal extends ObjectiveGoal +{ + public EquipDefaultBuildGoal(ClassesObjective objective) + { + super( + objective, + "Equip Armor", + "Put on your Iron Armor", + "When you wear a full set of armor, it will equip a class! The Iron set makes you " + + "into a Knight. Each class has different skills and is strong in its own way.", + null + ); + +// setStartMessageDelay(120); + } + + @Override + protected void customStart(Player player) + { + + } + + @Override + protected void customFinish(Player player) + { + + } + + @EventHandler + public void classEquip(ClassEquipEvent event) + { + if (contains(event.getUser())) + { + finish(event.getUser()); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/OpenClassManagerGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/OpenClassManagerGoal.java new file mode 100644 index 00000000..a67f3885 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/OpenClassManagerGoal.java @@ -0,0 +1,59 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClassesObjective; + +public class OpenClassManagerGoal extends ObjectiveGoal +{ + public OpenClassManagerGoal(ClassesObjective objective) + { + super( + objective, "Open Class Manager", + "Right-Click on the Enchantment Table", + "Each class has lots of different skills, and you can pick which ones you want to " + + "equip! Right-Click on an " + F.elem("Enchanting Table") + " to have a look at " + + "this menu.", + DyeColor.CYAN + ); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void interact(PlayerInteractEvent event) + { + if (!contains(event.getPlayer())) + { + return; + } + + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + return; + } + + if (!event.getClickedBlock().getType().equals(Material.ENCHANTMENT_TABLE)) + { + return; + } + + finish(event.getPlayer()); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/SelectBullsChargeGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/SelectBullsChargeGoal.java new file mode 100644 index 00000000..bc31e43e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/SelectBullsChargeGoal.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClassesObjective; +import mineplex.minecraft.game.classcombat.Class.ClientClass; +import mineplex.minecraft.game.classcombat.Class.IPvpClass; +import mineplex.minecraft.game.classcombat.Skill.ISkill; + +public class SelectBullsChargeGoal extends ObjectiveGoal +{ + public SelectBullsChargeGoal(ClassesObjective objective) + { + super(objective, "Open Class Manager", "Using the Class Manager, choose Bulls Charge for your Axe Skill"); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + getActivePlayers().forEach(uuid -> { + Player player = UtilPlayer.searchExact(uuid); + + if (player == null || !player.isOnline()) + { + return; + } + + ClientClass client = ClansManager.getInstance().getClassManager().Get(player); + + if (client.GetGameClass() != null) + { + IPvpClass gameClass = client.GetGameClass(); + + for (ISkill skill : gameClass.GetSkills()) + { + if (skill.GetName().toLowerCase().contains("bulls charge")) + { + finish(player); + break; + } + } + } + }); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/UseBullsChargeGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/UseBullsChargeGoal.java new file mode 100644 index 00000000..6c17de60 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/classes/UseBullsChargeGoal.java @@ -0,0 +1,50 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.classes; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.minecraft.game.classcombat.Class.ClassManager; +import mineplex.minecraft.game.classcombat.Class.ClientClass; +import mineplex.minecraft.game.classcombat.Class.IPvpClass; +import mineplex.minecraft.game.classcombat.Class.event.ClassEquipEvent; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ClassesObjective; +import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public class UseBullsChargeGoal extends ObjectiveGoal { + public UseBullsChargeGoal(ClassesObjective objective) { + super( + objective, + "Use Bulls Charge", + "Right-Click with Axe to use Bulls Charge", + "One of your default abilities as Knight is Bulls Charge. This ability will make " + + "you run faster for a short time, and deal extra damage to enemies.", + null + ); + } + + @Override + protected void customStart(Player player) { + ClientClass client = ClansManager.getInstance().getClassManager().Get(player); + + client.ResetSkills(player); + client.SetActiveCustomBuild(client.GetGameClass(), client.GetGameClass().getDefaultBuild()); + } + + @Override + protected void customFinish(Player player) { + } + + @EventHandler + public void checkSkill(SkillTriggerEvent event) { + if (contains(event.GetPlayer())) { + finish(event.GetPlayer()); + } + } + +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/energy/BuyEnergyGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/energy/BuyEnergyGoal.java new file mode 100644 index 00000000..40ab1a5c --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/energy/BuyEnergyGoal.java @@ -0,0 +1,64 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.energy; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.game.clans.clans.ClansManager; +import org.bukkit.DyeColor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.clans.event.EnergyPageBuildEvent; +import mineplex.game.clans.clans.event.PreEnergyShopBuyEvent; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.EnergyObjective; + +public class BuyEnergyGoal extends ObjectiveGoal +{ + public BuyEnergyGoal(EnergyObjective objective) + { + super( + objective, + "Buy Energy", + "Buy Clan Energy from the Energy Shop", + "You can buy Clan Energy at the Shops.", + DyeColor.RED + ); + } + + @Override + protected void customStart(Player player) + { + ClansManager.getInstance().runSyncLater(() -> { + UtilPlayer.message(player, F.main("Clans", "WARNING: Clan Energy is running very low!")); + UtilTextMiddle.display("Clan Energy", "is running very low", 10, 100, 10, player); + + player.playSound(player.getLocation(), Sound.NOTE_BASS, 1.0f, 1.0f); + }, 3L); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void energyBuy(PreEnergyShopBuyEvent event) + { + if (contains(event.getPlayer())) + { + finish(event.getPlayer()); + event.getPlayer().closeInventory(); + } + } + + @EventHandler + public void energyBuild(EnergyPageBuildEvent event) + { + if (contains(event.getPlayer())) + { + event.setFree(true); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/energy/ExplainEnergyGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/energy/ExplainEnergyGoal.java new file mode 100644 index 00000000..f4267c52 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/energy/ExplainEnergyGoal.java @@ -0,0 +1,57 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.energy; + +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.EnergyObjective; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; + +public class ExplainEnergyGoal extends ObjectiveGoal +{ + public ExplainEnergyGoal(EnergyObjective objective) + { + super( + objective, + "Check your Clans Energy", + "Type '/c' to check your Clans Energy", + "Owning land isn’t free! You will need to buy Energy from the Shops to retain " + + "ownership of it. If your Clan Energy ever reaches 0, you will lose your " + + "land claims!", + null + ); + } + + @Override + protected void customStart(Player player) + { + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1.0f, 1.0f); + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void onCommand(ClansCommandPreExecutedEvent event) + { + if(contains(event.getPlayer()) && event.getArguments().length == 0) + { + finish(event.getPlayer()); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onClick(ClansButtonClickEvent event) { + if(contains(event.getPlayer()) && event.getButtonType().equals(ClansButtonClickEvent.ButtonType.Energy)) + event.setCancelled(false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/GoToFieldsGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/GoToFieldsGoal.java new file mode 100644 index 00000000..0e416501 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/GoToFieldsGoal.java @@ -0,0 +1,75 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields; + +import java.util.UUID; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.UtilAlg; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FieldsObjective; + +public class GoToFieldsGoal extends ObjectiveGoal +{ + public GoToFieldsGoal(FieldsObjective objective) + { + super( + objective, + "Go to the Fields", + "Go to the Fields", + "The Fields are a very dangerous place where players come to fight and harvest " + + "resources!", + DyeColor.YELLOW + ); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void openGates(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + for (UUID uuid : getActivePlayers()) + { + if(UtilPlayer.searchExact(uuid) == null) return; + + getObjective().getPlugin().performGateCheck(UtilPlayer.searchExact(uuid), DyeColor.RED); + } + } + + @EventHandler + public void checkRegion(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (UUID uuid : getActivePlayers()) + { + Player player = UtilPlayer.searchExact(uuid); + if(player == null || !player.isOnline()) continue; + if (getObjective().getPlugin().isIn(player, ClansMainTutorial.Bounds.FIELDS)) + { + finish(player); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/IdentifyFieldsGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/IdentifyFieldsGoal.java new file mode 100644 index 00000000..e1d92f26 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/IdentifyFieldsGoal.java @@ -0,0 +1,63 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.DefaultHashMap; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FieldsObjective; + +public class IdentifyFieldsGoal extends ObjectiveGoal +{ + private DefaultHashMap> _ticksHeld = new DefaultHashMap<>(key -> new EnclosedObject<>(0)); + + public IdentifyFieldsGoal(FieldsObjective objective) + { + super(objective, "Identify The Fields", "By looking at your map, identify where the Fields are"); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + getActivePlayers().forEach(uuid -> + { + Player player = Bukkit.getPlayer(uuid); + + if (player != null && player.isOnline()) + { + if (player.getItemInHand() == null || player.getItemInHand().getType() != Material.MAP) + { + return; + } + + _ticksHeld.get(player.getName()).Set(_ticksHeld.get(player.getName()).Get() + 1); + + if (_ticksHeld.get(player.getName()).Get() >= 80) + { + finish(player); + } + } + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/MineDiamondsGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/MineDiamondsGoal.java new file mode 100644 index 00000000..aca99b03 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/MineDiamondsGoal.java @@ -0,0 +1,112 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields; + +import java.util.HashMap; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.TutorialRegion; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FieldsObjective; + +public class MineDiamondsGoal extends ObjectiveGoal +{ + private HashMap _playersMap; + + public MineDiamondsGoal(FieldsObjective objective) + { + super( + objective, + "Mine Diamonds", + "Mine Diamonds in the Fields", + "Mining in the Fields is a great way to make lots of money! The ores will " + + "regenerate over time. Be careful of enemies though!", + DyeColor.LIME + ); + + _playersMap = new HashMap<>(); + } + + @Override + protected void customStart(Player player) + { + player.getInventory().addItem(new ItemStack(Material.IRON_PICKAXE)); + + _playersMap.put(player.getUniqueId(), new AtomicInteger(0)); + } + + @Override + protected void customFinish(Player player) + { + _playersMap.remove(player.getUniqueId()); + } + + @Override + protected void customLeave(Player player) + { + _playersMap.remove(player.getUniqueId()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onBlockBreak(BlockBreakEvent event) + { + if (!contains(event.getPlayer()) || event.getBlock().getType() != Material.DIAMOND_ORE) + return; + + TutorialRegion region = getObjective().getPlugin().getRegion(event.getPlayer()); + if (getObjective().getPlugin().isIn(event.getBlock().getLocation(), region, ClansMainTutorial.Bounds.FIELDS)) + { + event.setCancelled(true); + event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation().add(0.5, 1.5, 0.5), new ItemStack(Material.DIAMOND)); + event.getBlock().setType(Material.COBBLESTONE); + + Bukkit.getServer().getScheduler().runTaskLater(getObjective().getJavaPlugin(), new Runnable() + { + @Override + public void run() + { + if (contains(event.getPlayer())) + { + event.getBlock().setType(Material.DIAMOND_ORE); + } + } + }, 20 * 10); + } + } + + @EventHandler + public void onItemPickup(PlayerPickupItemEvent event) + { + if (!contains(event.getPlayer())) + return; + + if (event.getItem().getItemStack().getType() == Material.DIAMOND) + { + if(_playersMap.get(event.getPlayer().getUniqueId()) == null) return; + int count = _playersMap.get(event.getPlayer().getUniqueId()).incrementAndGet(); + if (count == 10) + finish(event.getPlayer()); + } + } + + @Override + public String getDescription(Player player) + { + AtomicInteger count = _playersMap.get(player.getUniqueId()); + if (count == null) + return "Search for some diamonds in the Fields and mine them"; + else + return "Mine Diamonds " + count.get() + "/10"; + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/SellDiamondsGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/SellDiamondsGoal.java new file mode 100644 index 00000000..e1dd69ee --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/fields/SellDiamondsGoal.java @@ -0,0 +1,61 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.fields; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.event.ClansPlayerSellItemEvent; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FieldsObjective; +import org.bukkit.event.EventPriority; + +public class SellDiamondsGoal extends ObjectiveGoal +{ + public SellDiamondsGoal(FieldsObjective objective) + { + super( + objective, + "Sell Diamonds", + "Sell your Diamonds to the Mining Shop", + "Go back to the Shops and sell your precious diamonds!", + DyeColor.SILVER + ); + } + + @Override + protected void customStart(Player player) + { + TutorialSession session = getObjective().getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getObjective().getPlugin().getPoint(session.getRegion(), ClansMainTutorial.Point.MINING_SHOP)); + } + + @Override + protected void customFinish(Player player) + { + // Close Middle Gate + getObjective().getPlugin().destroyFences(getObjective().getPlugin().getRegion(player), DyeColor.RED); + + // Close Fields Gate + getObjective().getPlugin().destroyFences(getObjective().getPlugin().getRegion(player), DyeColor.BLACK); + } + + @EventHandler (priority = EventPriority.HIGH) + public void onSell(ClansPlayerSellItemEvent event) + { + if (contains(event.getPlayer())) + { + if (event.getItem().getType() == Material.DIAMOND) + { + event.setCancelled(false); + UtilInv.removeAll(event.getPlayer(), Material.DIAMOND, (byte) 0); + finish(event.getPlayer()); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/finalobj/DisbandClanGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/finalobj/DisbandClanGoal.java new file mode 100644 index 00000000..e70f7009 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/finalobj/DisbandClanGoal.java @@ -0,0 +1,65 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.finalobj; + +import mineplex.game.clans.clans.event.ClanDisbandedEvent; +import mineplex.game.clans.clans.gui.events.ClansButtonClickEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; + +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.tutorial.objective.Objective; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.event.ClansCommandExecutedEvent; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FinalObjective; + +public class DisbandClanGoal extends ObjectiveGoal +{ + public DisbandClanGoal(FinalObjective objective) + { + super( + objective, + "Disband Clan", + "Type '/c' and Disband your Clan", + "Now that the tutorial is almost finished, let’s delete your Clan. Disbanding a " + + "Clan will delete it, and unclaim all of your land.", + null + ); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + ClansManager.getInstance().resetLeftTimer(player.getUniqueId()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void teleport(ClanDisbandedEvent event) + { + if (!contains(event.getDisbander())) + { + return; + } + + event.setCancelled(true); + + UtilPlayer.message(event.getDisbander(), F.main("Clans", "You have disbanded your Tutorial Clan.")); + ClansManager.getInstance().getClanDataAccess().delete(ClansManager.getInstance().getClan(event.getDisbander()), null); + ClansManager.getInstance().resetLeftTimer(event.getDisbander().getUniqueId()); + finish(event.getDisbander()); + } + + + @EventHandler (priority = EventPriority.HIGHEST) + public void onClick(ClansButtonClickEvent event) { + if(contains(event.getPlayer()) && event.getButtonType().equals(ClansButtonClickEvent.ButtonType.Disband)) + event.setCancelled(false); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/finalobj/TpClanHomeGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/finalobj/TpClanHomeGoal.java new file mode 100644 index 00000000..18c5b08a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/finalobj/TpClanHomeGoal.java @@ -0,0 +1,91 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.finalobj; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.delayedtask.DelayedTask; +import mineplex.core.delayedtask.DelayedTaskClient; +import mineplex.game.clans.clans.event.ClansCommandPreExecutedEvent; +import mineplex.game.clans.tutorial.objective.Objective; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.tutorial.tutorials.clans.objective.FinalObjective; + +public class TpClanHomeGoal extends ObjectiveGoal +{ + public TpClanHomeGoal(FinalObjective objective) + { + super( + objective, + "Teleport to Clan Home", + "Type '/c home' to teleport to Clan Home", + "You can teleport back to your Clan Home at any time! If enemies break your bed, then you cannot teleport to it!", + null + ); + +// setStartMessageDelay(120); + } + + @Override + protected void customStart(Player player) + { + } + + @Override + protected void customFinish(Player player) + { + } + + @EventHandler + public void teleport(ClansCommandPreExecutedEvent event) + { + if (event.getArguments().length != 1 || !event.getArguments()[0].equalsIgnoreCase("home")) + { + return; + } + + if (!contains(event.getPlayer())) + { + return; + } + + DelayedTask.Instance.doDelay( + event.getPlayer(), + "Tutorial Home Teleport", + new Callback() + { + @Override + public void run(DelayedTaskClient data) + { + UtilPlayer.message(event.getPlayer(), F.main("Clans", "You have teleported to your Clan's Home.")); + event.getPlayer().teleport(getObjective().getPlugin().getTutorialSession(event.getPlayer()).getHomeLocation()); + finish(event.getPlayer()); + } + }, + new Callback() + { + @Override + public void run(DelayedTaskClient data) + { + UtilTextMiddle.display("", "Teleporting to Clan Home in " + F.time(UtilTime.MakeStr(Math.max(0, data.getTimeLeft("Tutorial Home Teleport")))), 0, 5, 0, data.getPlayer()); + } + }, + new Callback() + { + @Override + public void run(DelayedTaskClient data) + { + UtilPlayer.message(data.getPlayer(), F.main("Clans", "Teleport has been cancelled due to movement.")); + } + }, + 15 * 1000, // 15 second cooldown + false + ); + + event.setCancelled(true); + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/GoToShopsGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/GoToShopsGoal.java new file mode 100644 index 00000000..0177f3f9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/GoToShopsGoal.java @@ -0,0 +1,77 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.shops; + +import java.util.UUID; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ShopsObjective; + +public class GoToShopsGoal extends ObjectiveGoal +{ + public GoToShopsGoal(ShopsObjective objective) + { + super( + objective, + "Go to the Shops", + "Walk to the Shops", + "The shops are the place where you can buy and sell all sorts of items! " + + "The Shops are a " + F.elem("Safe Zone") + ", meaning meaning that players cannot hurt each other.", + DyeColor.LIGHT_BLUE + ); + } + + @Override + protected void customStart(Player player) + { + + } + + @Override + protected void customFinish(Player player) + { + + } + + @EventHandler + public void openGates(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + for (UUID uuid : getActivePlayers()) + { + if(UtilPlayer.searchExact(uuid) == null) continue; + getObjective().getPlugin().performGateCheck(UtilPlayer.searchExact(uuid), DyeColor.BROWN); + } + } + + @EventHandler + public void checkRegion(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (UUID uuid : getActivePlayers()) + { + Player player = UtilPlayer.searchExact(uuid); + if(player == null || !player.isOnline()) continue; + if (getObjective().getPlugin().isIn(player, ClansMainTutorial.Bounds.SHOPS)) + { + finish(player); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/PurchaseGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/PurchaseGoal.java new file mode 100644 index 00000000..a5ba6bc0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/PurchaseGoal.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.shops; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.game.clans.clans.event.ClansPlayerBuyItemEvent; +import mineplex.game.clans.clans.event.ClansShopAddButtonEvent; +import mineplex.game.clans.tutorial.objective.Objective; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import org.bukkit.event.EventPriority; + +public class PurchaseGoal extends ObjectiveGoal +{ + private Material _material; + + public PurchaseGoal(Objective objective, Material material, String name, String description) + { + super(objective, name, description); + _material = material; + + setDisplayStartMessage(false); + setDisplayFinishMessage(false); + } + + public PurchaseGoal(Objective objective, Material material, String name, String description, + String helpText) + { + super(objective, name, description, helpText, null); + _material = material; + + setDisplayStartMessage(false); + setDisplayFinishMessage(false); + } + + @Override + protected void customStart(Player player) + { + + } + + @Override + protected void customFinish(Player player) + { + + } + + @EventHandler + public void button(ClansShopAddButtonEvent event) + { + if (contains(event.getPlayer()) && event.getMaterial() == _material) + { + event.setBuyPrice(0); + } + } + + @EventHandler (priority = EventPriority.HIGH) + public void buy(final ClansPlayerBuyItemEvent event) + { + if (contains(event.getPlayer()) && event.getItem().getType() == _material) + { + event.setCancelled(false); + finish(event.getPlayer()); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/SellPotatoesGoal.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/SellPotatoesGoal.java new file mode 100644 index 00000000..abfca5e9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/objective/goals/shops/SellPotatoesGoal.java @@ -0,0 +1,59 @@ +package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.shops; + +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.event.ClansPlayerSellItemEvent; +import mineplex.game.clans.tutorial.TutorialSession; +import mineplex.game.clans.tutorial.objective.ObjectiveGoal; +import mineplex.game.clans.tutorial.tutorials.clans.ClansMainTutorial; +import mineplex.game.clans.tutorial.tutorials.clans.objective.ShopsObjective; +import org.bukkit.event.EventPriority; + +public class SellPotatoesGoal extends ObjectiveGoal +{ + public SellPotatoesGoal(ShopsObjective objective) + { + super( + objective, + "Sell Potatoes", + "Sell your Potatoes to the " + F.elem("Organic Produce Shop"), + "Farming is a great way to make money in Clans. Build a farm in your land, " + + "harvest the crops, and sell it to the shops for profit!", + DyeColor.PINK + ); + } + + @Override + protected void customStart(Player player) + { + TutorialSession session = getObjective().getPlugin().getTutorialSession(player); + session.setMapTargetLocation(getObjective().getPlugin().getPoint(session.getRegion(), ClansMainTutorial.Point.FARMING_SHOP)); + } + + @Override + protected void customFinish(Player player) + { + // Shops Fences Closed + getObjective().getPlugin().spawnFences(getObjective().getPlugin().getRegion(player), DyeColor.BROWN); + + // Remove all potatoes from inventory + UtilInv.removeAll(player, Material.POTATO_ITEM, (byte) 0); + } + + @EventHandler (priority = EventPriority.HIGH) + public void onSell(ClansPlayerSellItemEvent event) + { + if (contains(event.getPlayer())) { + if (event.getItem().getType() == Material.POTATO_ITEM) { + event.setCancelled(false); + finish(event.getPlayer()); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/repository/TutorialRepository.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/repository/TutorialRepository.java new file mode 100644 index 00000000..e7d76474 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/repository/TutorialRepository.java @@ -0,0 +1,66 @@ +package mineplex.game.clans.tutorial.tutorials.clans.repository; + +import java.util.UUID; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.EnclosedObject; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.database.MinecraftRepository; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class TutorialRepository extends RepositoryBase +{ + private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS clansTutorial (uuid VARCHAR(36), timesPlayed INT, PRIMARY KEY (uuid));"; + private static final String GET = "SELECT * FROM clansTutorial WHERE uuid = ?;"; + private static final String INSERT = "INSERT INTO clansTutorial (uuid, timesPlayed) VALUES (?, ?);"; + private static final String UPDATE = "UPDATE clansTutorial SET timesPlayed=? WHERE uuid=?;"; + + private CoreClientManager _clientManager; + + public TutorialRepository(CoreClientManager clientManager) + { + super(DBPool.getAccount()); + + _clientManager = clientManager; + } + + public void SetTimesPlayed(UUID uuid, int timesPlayed) + { + // Prevent duplicate entries for individuals + executeQuery(GET, result -> + { + if (result.next()) + executeUpdate(UPDATE, new ColumnInt("timesPlayed", timesPlayed), new ColumnVarChar("uuid", 36, uuid.toString())); + else + executeUpdate(INSERT, new ColumnVarChar("uuid", 36, uuid.toString()), new ColumnInt("timesPlayed", timesPlayed)); + }, new ColumnVarChar("uuid", 36, uuid.toString())); + } + + public int GetTimesPlayed(UUID uuid) + { + EnclosedObject status = new EnclosedObject<>(); + + executeQuery(GET, result -> + { + if (result.next()) + status.Set(result.getInt("timesPlayed")); + else + status.Set(0); + }, new ColumnVarChar("uuid", 36, uuid.toString())); + + return status.Get(); + } + + public int GetTimesPlayed(String name) + { + return GetTimesPlayed(UUIDFetcher.getUUIDOf(name)); + } + + protected void initialize() + { + executeUpdate(CREATE_TABLE); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/visual/VisualManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/visual/VisualManager.java new file mode 100644 index 00000000..9fd96caf --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/visual/VisualManager.java @@ -0,0 +1,35 @@ +package mineplex.game.clans.tutorial.visual; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; + +public class VisualManager extends MiniPlugin +{ + public VisualManager(JavaPlugin plugin) + { + super("Visual", plugin); + } + + public void setTitleMessage(Player player, String message, String desc, int timer, boolean displayNow) + { + + } + + public void displayTitleMessage(Player player, String message, String desc) + { + + } + + public void playFinish(Player player) + { + player.playSound(player.getLocation(), Sound.LEVEL_UP, 1f, 1f); + } + + public void clear(Player player) + { + + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java new file mode 100644 index 00000000..141e52cb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Clans/src/mineplex/game/clans/world/WorldManager.java @@ -0,0 +1,158 @@ +package mineplex.game.clans.world; + +import java.util.*; + +import mineplex.core.common.util.UtilWorld; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import org.bukkit.Location; + +public class WorldManager extends MiniPlugin +{ + private static final Map CULL_LIMITS = new HashMap<>(); + private static final Set MINECART_TYPES = new HashSet<>(); + private static final int MIN_RANGE = 64; + private static final int MIN_RANGE_SQUARED = MIN_RANGE * MIN_RANGE; + + static + { + // Animals + CULL_LIMITS.put(EntityType.BAT, 50); + CULL_LIMITS.put(EntityType.CHICKEN, 150); + CULL_LIMITS.put(EntityType.COW, 150); + CULL_LIMITS.put(EntityType.HORSE, 50); + CULL_LIMITS.put(EntityType.IRON_GOLEM, 50); + CULL_LIMITS.put(EntityType.MUSHROOM_COW, 50); + CULL_LIMITS.put(EntityType.OCELOT, 50); + CULL_LIMITS.put(EntityType.PIG, 150); + CULL_LIMITS.put(EntityType.RABBIT, 50); + CULL_LIMITS.put(EntityType.SHEEP, 150); + CULL_LIMITS.put(EntityType.WOLF, 150); + + // Monsters + CULL_LIMITS.put(EntityType.CAVE_SPIDER, 100); + CULL_LIMITS.put(EntityType.CREEPER, 100); + CULL_LIMITS.put(EntityType.ENDERMAN, 50); + CULL_LIMITS.put(EntityType.ENDERMITE, 50); + CULL_LIMITS.put(EntityType.SILVERFISH, 50); + CULL_LIMITS.put(EntityType.SKELETON, 100); + CULL_LIMITS.put(EntityType.SLIME, 50); + CULL_LIMITS.put(EntityType.SPIDER, 100); + CULL_LIMITS.put(EntityType.ZOMBIE, 100); + + // Nether + CULL_LIMITS.put(EntityType.BLAZE, 50); + CULL_LIMITS.put(EntityType.GHAST, 50); + CULL_LIMITS.put(EntityType.MAGMA_CUBE, 50); + CULL_LIMITS.put(EntityType.PIG_ZOMBIE, 50); + + MINECART_TYPES.add(EntityType.MINECART); + MINECART_TYPES.add(EntityType.MINECART_CHEST); + MINECART_TYPES.add(EntityType.MINECART_COMMAND); + MINECART_TYPES.add(EntityType.MINECART_FURNACE); + MINECART_TYPES.add(EntityType.MINECART_HOPPER); + MINECART_TYPES.add(EntityType.MINECART_MOB_SPAWNER); + MINECART_TYPES.add(EntityType.MINECART_TNT); + } + + public WorldManager(JavaPlugin plugin) + { + super("Clan World Manager", plugin); + } + + @EventHandler + public void cullMobs(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOW) + return; + + for (World world : getPlugin().getServer().getWorlds()) + { + List players = world.getPlayers(); + Map> entities = new HashMap<>(); + // For optimization reasons reuse location objects + Location entityLocation = new Location(world, 0, 0, 0); + Location playerLocation = new Location(world, 0, 0, 0); + + for (Entity entity : world.getEntities()) + { + if (entity.getCustomName() != null) + { + continue; + } + + EntityType entityType = entity.getType(); + + if (entityType == EntityType.ARROW) + { + if (entity.getTicksLived() > 800) + { + entity.remove(); + } + } + else if (entityType == EntityType.DROPPED_ITEM) + { + if (entity.getTicksLived() > 2400) + { + entity.remove(); + } + } + else if (CULL_LIMITS.containsKey(entityType)) + { + boolean cull = true; + entity.getLocation(entityLocation); + for (Player player : players) + { + player.getLocation(playerLocation); + if (playerLocation.distanceSquared(entityLocation) <= MIN_RANGE_SQUARED) + { + cull = false; + break; + } + } + if (cull) + { + entities.computeIfAbsent(entityType, key -> new HashSet<>()).add(entity); + } + } + else if (MINECART_TYPES.contains(entityType)) + { + if (entity.getTicksLived() > 800) + { + entity.remove(); + } + } + } + + for (Map.Entry> entry : entities.entrySet()) + { + cull(entry.getKey(), entry.getValue(), CULL_LIMITS.get(entry.getKey())); + } + } + } + + private void cull(EntityType type, Set ents, int limit) + { + Iterator iterator = ents.iterator(); + int culled = 0; + while (iterator.hasNext() && ents.size() > limit) + { + Entity entity = iterator.next(); + entity.remove(); + iterator.remove(); + culled++; + } + if (culled != 0) + { + log("Culled " + culled + " " + type); + } + } +} diff --git a/Plugins[Modified]/Mineplex.Game.Nano/dependency-reduced-pom.xml b/Plugins[Modified]/Mineplex.Game.Nano/dependency-reduced-pom.xml deleted file mode 100644 index 5aae6d8d..00000000 --- a/Plugins[Modified]/Mineplex.Game.Nano/dependency-reduced-pom.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - mineplex-plugin - com.mineplex - dev-SNAPSHOT - ../plugin.xml - - 4.0.0 - mineplex-game-nano - NanoGames - - diff --git a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoGames.java b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoGames.java index a904e746..8306b6af 100644 --- a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoGames.java +++ b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoGames.java @@ -1,5 +1,13 @@ package mineplex.game.nano; +import static mineplex.core.Managers.require; + +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.plugin.ServicePriority; +import org.bukkit.plugin.java.JavaPlugin; + import mineplex.core.CustomTagFix; import mineplex.core.FoodDupeFix; import mineplex.core.PacketsInteractionFix; @@ -10,6 +18,9 @@ import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blood.Blood; import mineplex.core.boosters.BoosterManager; import mineplex.core.chat.Chat; +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.communities.CommunityManager; @@ -39,6 +50,8 @@ import mineplex.core.preferences.PreferencesManager; import mineplex.core.profileCache.ProfileCacheManager; import mineplex.core.punish.Punish; import mineplex.core.recharge.Recharge; +import mineplex.core.report.ReportManager; +import mineplex.core.report.ReportPlugin; import mineplex.core.serverConfig.ServerConfiguration; import mineplex.core.sound.SoundNotifier; import mineplex.core.stats.StatsManager; @@ -55,13 +68,10 @@ import mineplex.core.updater.Updater; import mineplex.core.velocity.VelocityFix; import mineplex.core.visibility.VisibilityManager; import mineplex.core.website.WebsiteLinkManager; +import mineplex.game.nano.game.Game; import mineplex.minecraft.game.core.combat.CombatManager; import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.DamageManager; -import org.bukkit.Bukkit; -import org.bukkit.plugin.java.JavaPlugin; - -import static mineplex.core.Managers.require; public class NanoGames extends JavaPlugin { @@ -84,9 +94,7 @@ public class NanoGames extends JavaPlugin return target instanceof LivingEntity && game != null && game.isLive(); } }, this, ServicePriority.Normal); - - */ - + */ Bukkit.setSpawnRadius(0); getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS); getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY)); @@ -150,13 +158,10 @@ public class NanoGames extends JavaPlugin new CustomTagFix(this, packetHandler); new PacketsInteractionFix(this, packetHandler); - /* SnapshotManager snapshotManager = new SnapshotManager(this, new SnapshotRepository(serverStatusManager.getCurrentServerName(), getLogger())); ReportManager reportManager = new ReportManager(this, snapshotManager, clientManager, incognito, punish, serverStatusManager.getRegion(), serverStatusManager.getCurrentServerName(), 3); new SnapshotPlugin(this, snapshotManager, clientManager); new ReportPlugin(this, reportManager); - - */ new VelocityFix(this); new FoodDupeFix(this); diff --git a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoManager.java b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoManager.java index a9574d40..5785ad05 100644 --- a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoManager.java +++ b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/NanoManager.java @@ -1,11 +1,25 @@ package mineplex.game.nano; +import java.util.HashSet; +import java.util.Set; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +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.account.permissions.Permission; import mineplex.core.account.permissions.PermissionGroup; import mineplex.core.achievement.AchievementManager; +//import mineplex.core.antihack.AntiHack; import mineplex.core.boosters.BoosterManager; import mineplex.core.chat.Chat; import mineplex.core.chat.format.LevelFormatComponent; @@ -44,17 +58,6 @@ import mineplex.minecraft.game.core.IRelation; import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.serverdata.data.ServerGroup; -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.HashSet; -import java.util.Set; @ReflectivelyCreateMiniPlugin public class NanoManager extends MiniPlugin implements IRelation @@ -109,6 +112,8 @@ public class NanoManager extends MiniPlugin implements IRelation // Booster private final BoosterManager _boosterManager; + // AntiCheat + //private final AntiHack _antiHack; // Packet private final PacketHandler _packetHandler; @@ -188,6 +193,8 @@ public class NanoManager extends MiniPlugin implements IRelation _boosterManager = require(BoosterManager.class); + //_antiHack = require(AntiHack.class); + _packetHandler = require(PacketHandler.class); _npcManager = require(NewNPCManager.class); @@ -413,6 +420,13 @@ public class NanoManager extends MiniPlugin implements IRelation return _boosterManager; } + /* + public AntiHack getAntiHack() + { + return _antiHack; + } + */ + public PacketHandler getPacketHandler() { return _packetHandler; diff --git a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/Game.java b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/Game.java index eadd51a4..7f302297 100644 --- a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/Game.java +++ b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/Game.java @@ -1,5 +1,16 @@ package mineplex.game.nano.game; +import java.io.File; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +//import com.mineplex.anticheat.checks.move.Glide; + +//import mineplex.core.antihack.AntiHack; import mineplex.core.common.util.UtilServer; import mineplex.core.lifetimes.Lifetimed; import mineplex.core.lifetimes.ListenerComponent; @@ -25,13 +36,6 @@ import mineplex.game.nano.game.components.world.GameWaterComponent; import mineplex.game.nano.game.components.world.GameWorldComponent; import mineplex.game.nano.game.event.GameStateChangeEvent; import mineplex.game.nano.world.GameWorld; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.entity.Player; - -import java.io.File; -import java.util.List; public abstract class Game extends ListenerComponent implements Lifetimed, TeamComponent, SpectatorComponent, CurrencyComponent, StatsComponent { @@ -94,6 +98,8 @@ public abstract class Game extends ListenerComponent implements Lifetimed, TeamC _endComponent = new GameEndComponent(this); new GeneralStatsTracker(this); + + //manager.getAntiHack().addIgnoredCheck(Glide.class); } public final void setupGameWorld(File mapZip) @@ -132,6 +138,11 @@ public abstract class Game extends ListenerComponent implements Lifetimed, TeamC disable(); super.deactivate(); + + /* + AntiHack antiHack = _manager.getAntiHack(); + antiHack.resetIgnoredChecks(); + */ } public final NanoManager getManager() diff --git a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/GamePlayerManager.java b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/GamePlayerManager.java index 4a933d8b..8cff36fa 100644 --- a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/GamePlayerManager.java +++ b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/components/player/GamePlayerManager.java @@ -76,9 +76,11 @@ public class GamePlayerManager extends GameManager implements ComponentHook { scoreboard.writeNewLine(); diff --git a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/wizards/Wizards.java b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/wizards/Wizards.java index d5c2d4d0..e99161a5 100644 --- a/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/wizards/Wizards.java +++ b/Plugins[Modified]/Mineplex.Game.Nano/src/mineplex/game/nano/game/games/wizards/Wizards.java @@ -1,8 +1,31 @@ package mineplex.game.nano.game.games.wizards; -import mineplex.core.common.util.*; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.Speed; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.itemstack.ItemBuilder; import mineplex.game.nano.NanoManager; import mineplex.game.nano.game.GameType; @@ -18,20 +41,6 @@ import mineplex.minecraft.game.core.combat.CombatComponent; import mineplex.minecraft.game.core.combat.DeathMessageType; import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import java.util.concurrent.TimeUnit; public class Wizards extends ScoredSoloGame { @@ -97,6 +106,8 @@ public class Wizards extends ScoredSoloGame new DoubleJumpComponent(this); + //_manager.getAntiHack().addIgnoredCheck(Speed.class); + //_manager.getAntiHack().addIgnoredCheck(Glide.class); } @Override diff --git a/Plugins[Modified]/Mineplex.Game.Nano/target/classes/plugin.yml b/Plugins[Modified]/Mineplex.Game.Nano/target/classes/plugin.yml new file mode 100644 index 00000000..dd12b1ff --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Nano/target/classes/plugin.yml @@ -0,0 +1,4 @@ +name: NanoGames +main: mineplex.game.nano.NanoGames +version: 0.1 +loadbefore: [MineplexAnticheat] diff --git a/Plugins[Modified]/Mineplex.Game.Nano/target/maven-archiver/pom.properties b/Plugins[Modified]/Mineplex.Game.Nano/target/maven-archiver/pom.properties new file mode 100644 index 00000000..8a244dd5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Nano/target/maven-archiver/pom.properties @@ -0,0 +1,4 @@ +#Created by Apache Maven 3.8.1 +groupId=com.mineplex +artifactId=mineplex-game-nano +version=dev-SNAPSHOT diff --git a/Plugins[Modified]/Mineplex.Game.Nano/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Plugins[Modified]/Mineplex.Game.Nano/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 00000000..f3aa1c65 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Nano/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,156 @@ +mineplex\game\nano\game\components\scoreboard\NanoScoreboard.class +mineplex\game\nano\game\components\team\GameTeam.class +mineplex\game\nano\game\games\findores\FindOres$OreType.class +mineplex\game\nano\game\event\PlayerGameRespawnEvent.class +mineplex\game\nano\game\games\minekart\KartCheckpoint.class +mineplex\game\nano\game\components\Disposable.class +mineplex\game\nano\NanoManager.class +mineplex\game\nano\game\games\parkour\Parkour$ParkourPlace.class +mineplex\game\nano\game\games\redgreenlight\RedGreenLight$LightState.class +mineplex\game\nano\game\games\quick\challenges\ChallengeFood.class +mineplex\game\nano\game\components\player\DoubleJumpComponent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeEnchantItem.class +mineplex\game\nano\game\games\kingslime\KingSlime$1.class +mineplex\game\nano\game\components\stats\GeneralStatsTracker.class +mineplex\game\nano\game\SoloGame.class +mineplex\game\nano\lobby\AFKManager$AFKData.class +mineplex\game\nano\game\components\compass\GameCompassComponent.class +mineplex\game\nano\NanoGames.class +mineplex\game\nano\game\components\player\GamePlayerComponent.class +mineplex\game\nano\game\components\end\GameEndComponent$2.class +mineplex\game\nano\game\components\team\TeamComponent.class +mineplex\game\nano\NanoPlayer.class +mineplex\game\nano\game\event\PlayerGameApplyEvent.class +mineplex\game\nano\game\components\player\GiveItemComponent.class +mineplex\game\nano\game\games\slimecycles\SlimeBike.class +mineplex\game\nano\game\games\chickenshoot\ChickenShoot.class +mineplex\game\nano\game\components\world\GameWorldComponent.class +mineplex\game\nano\game\games\minekart\MineKart.class +mineplex\game\nano\game\games\findores\FindOres.class +mineplex\game\nano\game\games\quick\challenges\ChallengePickASide.class +mineplex\game\nano\game\event\GameEvent.class +mineplex\game\nano\game\components\end\GameEndComponent.class +mineplex\game\nano\game\components\player\NightVisionComponent.class +mineplex\game\nano\game\games\quick\Quick.class +mineplex\game\nano\game\games\wizards\spells\SpellTNT.class +mineplex\game\nano\game\games\spleef\Spleef.class +mineplex\game\nano\game\components\damage\GameDamageManager.class +mineplex\game\nano\game\games\colourchange\ColourChange.class +mineplex\game\nano\game\Game$GameState.class +mineplex\game\nano\commands\game\GameCommand.class +mineplex\game\nano\game\event\PlayerDeathOutEvent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeSpin.class +mineplex\game\nano\game\components\stats\StatTracker.class +mineplex\game\nano\game\games\deathtag\DeathTag.class +mineplex\game\nano\game\components\compass\GameCompassShop.class +mineplex\game\nano\game\components\compass\GameCompassPage.class +mineplex\game\nano\game\components\team\GameTeamComponent.class +mineplex\game\nano\game\components\damage\GameDamageComponent.class +mineplex\game\nano\cycle\GameCycle$1.class +mineplex\game\nano\game\components\currency\GameCurrencyManager$GameSessionData.class +mineplex\game\nano\game\games\musicminecart\MusicMinecarts.class +mineplex\game\nano\game\games\wizards\Spell.class +mineplex\game\nano\GameManager.class +mineplex\game\nano\status\GameStatusManager.class +mineplex\game\nano\game\games\quick\challenges\ChallengeZombies.class +mineplex\game\nano\game\components\currency\GameCurrencyManager.class +mineplex\game\nano\game\games\oits\SnowballTrouble.class +mineplex\game\nano\game\games\quick\challenges\ChallengeIgniteTNT.class +mineplex\game\nano\game\event\PlayerStateChangeEvent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeReverseRunner.class +mineplex\game\nano\game\games\wizards\Spell$SpellType.class +mineplex\game\nano\game\games\quick\challenges\ChallengeIntoVoid.class +mineplex\game\nano\game\components\player\GamePlayerManager.class +mineplex\game\nano\game\games\minekart\KartController$DriftDirection.class +mineplex\game\nano\game\games\microbattle\components\TeamArmourComponent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeRedBlocks.class +mineplex\game\nano\cycle\GameCycle.class +mineplex\game\nano\game\games\quick\challenges\ChallengePlatform.class +mineplex\game\nano\game\games\quick\challenges\ChallengePunchAPig.class +mineplex\game\nano\game\GameComponent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeSpleef$1.class +mineplex\game\nano\game\games\wizards\spells\SpellLevitation.class +mineplex\game\nano\game\games\kingslime\KingSlime.class +mineplex\game\nano\game\GamePlacements.class +mineplex\game\nano\game\games\bawkbawk\BawkBawk.class +mineplex\game\nano\game\components\spectator\GameSpectatorComponent.class +mineplex\game\nano\game\components\world\GameWorldManager.class +mineplex\game\nano\game\games\parkour\Parkour.class +mineplex\game\nano\game\games\quick\challenges\ChallengeThrowEggs.class +mineplex\game\nano\game\ScoredSoloGame.class +mineplex\game\nano\commands\game\GameStartCommand.class +mineplex\game\nano\game\games\jumprope\JumpRope.class +mineplex\game\nano\game\games\territory\Territory.class +mineplex\game\nano\game\components\stats\GameStatsComponent.class +mineplex\game\nano\game\components\currency\CurrencyComponent.class +mineplex\game\nano\game\games\minekart\KartController.class +mineplex\game\nano\game\games\minekart\Kart.class +mineplex\game\nano\game\games\quick\ChallengeType.class +mineplex\game\nano\lobby\AFKManager$Perm.class +mineplex\game\nano\game\components\currency\GameCurrencyManager$Perm.class +mineplex\game\nano\game\games\microbattle\components\MapCourruptionComponent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeCrouch.class +mineplex\game\nano\game\components\player\GamePlayerManager$Perm.class +mineplex\game\nano\game\event\GameStateChangeEvent.class +mineplex\game\nano\game\TeamGame.class +mineplex\game\nano\game\games\musicminecart\MusicMinecarts$1.class +mineplex\game\nano\game\games\redgreenlight\RedGreenLight.class +mineplex\game\nano\game\games\quick\challenges\ChallengeSpeedBridge.class +mineplex\game\nano\commands\spectator\SpectatorCommand.class +mineplex\game\nano\lobby\ReturnToHubManager$2.class +mineplex\game\nano\game\games\copycat\CopyCat.class +mineplex\game\nano\game\games\quick\challenges\ChallengeBlockSnake.class +mineplex\game\nano\game\games\quick\challenges\ChallengeAvoidTNT.class +mineplex\game\nano\game\components\world\GameWaterComponent.class +mineplex\game\nano\game\games\quick\challenges\ChallengeCraftItem.class +mineplex\game\nano\game\games\minekart\MineKart$1.class +mineplex\game\nano\game\components\prepare\GamePrepareComponent.class +mineplex\game\nano\game\games\reversetag\ReverseTag.class +mineplex\game\nano\NanoManager$Perm.class +mineplex\game\nano\commands\game\GameStopCommand.class +mineplex\game\nano\game\games\quick\challenges\ChallengeSumo.class +mineplex\game\nano\game\roomed\RoomedSoloGame.class +mineplex\game\nano\commands\game\GameCycleCommand.class +mineplex\game\nano\game\Game.class +mineplex\game\nano\game\games\dropper\Dropper.class +mineplex\game\nano\game\games\musicminecart\MusicMinecarts$2.class +mineplex\game\nano\game\components\player\GamePlayerManager$1.class +mineplex\game\nano\lobby\ReturnToHubManager$1.class +mineplex\game\nano\game\games\quick\Quick$1.class +mineplex\game\nano\game\games\quick\Quick$Perm.class +mineplex\game\nano\game\components\end\GameEndComponent$AnnouncementType.class +mineplex\game\nano\game\components\ComponentHook.class +mineplex\game\nano\game\games\hotpotato\HotPotato.class +mineplex\game\nano\game\roomed\Room.class +mineplex\game\nano\game\event\GameTimeoutEvent.class +mineplex\game\nano\game\games\sploor\Sploor.class +mineplex\game\nano\game\games\quick\challenges\ChallengeSlimeJump.class +mineplex\game\nano\game\games\quick\challenges\ChallengeStandStill.class +mineplex\game\nano\game\components\currency\GameCurrencyManager$1.class +mineplex\game\nano\game\games\quick\challenges\ChallengeMilkCow.class +mineplex\game\nano\game\games\slimecycles\SlimeCycles.class +mineplex\game\nano\game\games\quick\challenges\ChallengePole.class +mineplex\game\nano\game\games\quick\challenges\ChallengePlayMusic.class +mineplex\game\nano\game\games\wizards\Wizards.class +mineplex\game\nano\game\games\quick\ChallengeSetCommand.class +mineplex\game\nano\world\GameWorld.class +mineplex\game\nano\game\games\quick\challenges\ChallengeSpleef.class +mineplex\game\nano\game\games\copycat\CopyCat$SealBreakerRoom.class +mineplex\game\nano\game\components\spectator\SpectatorComponent.class +mineplex\game\nano\game\components\stats\StatsComponent.class +mineplex\game\nano\lobby\ReturnToHubManager.class +mineplex\game\nano\status\GameStatusManager$Perm.class +mineplex\game\nano\lobby\AFKManager.class +mineplex\game\nano\commands\game\GameSetCommand.class +mineplex\game\nano\game\games\microbattle\MicroBattle.class +mineplex\game\nano\game\games\quick\Challenge.class +mineplex\game\nano\game\games\quick\challenges\ChallengeMaths.class +mineplex\game\nano\lobby\LobbyManager.class +mineplex\game\nano\game\components\prepare\GamePrepareComponent$1.class +mineplex\game\nano\game\components\scoreboard\GameScoreboardComponent.class +mineplex\game\nano\game\games\quick\ChallengeWinConditions.class +mineplex\game\nano\game\games\wizards\spells\SpellFireball.class +mineplex\game\nano\game\GameType.class +mineplex\game\nano\game\components\end\GameEndComponent$1.class +mineplex\game\nano\game\games\wizards\spells\SpellFortify.class +mineplex\game\nano\lobby\ReturnToHubManager$Perm.class diff --git a/Plugins[Modified]/Mineplex.Game.Nano/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Plugins[Modified]/Mineplex.Game.Nano/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 00000000..1f13a94d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Game.Nano/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,125 @@ +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\PlayerDeathOutEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\minekart\KartCheckpoint.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeSpeedBridge.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeEnchantItem.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\GameStateChangeEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\territory\Territory.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\NanoPlayer.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\hotpotato\HotPotato.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeThrowEggs.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\wizards\Spell.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\wizards\spells\SpellLevitation.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\ScoredSoloGame.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\spectator\SpectatorComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\world\GameWorldManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeCrouch.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeMaths.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\colourchange\ColourChange.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\Challenge.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\chickenshoot\ChickenShoot.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengePole.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\world\GameWorld.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\player\NightVisionComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\microbattle\components\TeamArmourComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengePlatform.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\damage\GameDamageComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\player\GiveItemComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\commands\game\GameStopCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\currency\GameCurrencyManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\Quick.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\lobby\AFKManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeBlockSnake.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\wizards\spells\SpellFortify.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengePickASide.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeIntoVoid.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\minekart\KartController.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\sploor\Sploor.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\commands\game\GameStartCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengePlayMusic.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeReverseRunner.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\redgreenlight\RedGreenLight.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\stats\GameStatsComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeSpin.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\findores\FindOres.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeStandStill.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\team\TeamComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\ChallengeType.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\status\GameStatusManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\wizards\Wizards.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeIgniteTNT.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\commands\spectator\SpectatorCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\ComponentHook.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\stats\GeneralStatsTracker.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\SoloGame.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\commands\game\GameSetCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\roomed\RoomedSoloGame.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\stats\StatsComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\wizards\spells\SpellTNT.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\Disposable.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\GameEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\oits\SnowballTrouble.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\reversetag\ReverseTag.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\NanoGames.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\jumprope\JumpRope.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\parkour\Parkour.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeAvoidTNT.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeFood.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\minekart\MineKart.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\compass\GameCompassPage.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\cycle\GameCycle.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\player\GamePlayerComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\PlayerStateChangeEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\end\GameEndComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\player\GamePlayerManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\Game.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\bawkbawk\BawkBawk.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\minekart\Kart.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\spleef\Spleef.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\roomed\Room.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\deathtag\DeathTag.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\GameManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeZombies.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\player\DoubleJumpComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\commands\game\GameCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\stats\StatTracker.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\PlayerGameApplyEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\world\GameWorldComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeRedBlocks.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\copycat\CopyCat.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\prepare\GamePrepareComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\compass\GameCompassShop.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeSumo.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\slimecycles\SlimeCycles.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\wizards\spells\SpellFireball.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\GameComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\GameTimeoutEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\GamePlacements.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\ChallengeWinConditions.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\dropper\Dropper.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeSpleef.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\damage\GameDamageManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\slimecycles\SlimeBike.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\lobby\LobbyManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeCraftItem.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\NanoManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\kingslime\KingSlime.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\microbattle\components\MapCourruptionComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\scoreboard\GameScoreboardComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\team\GameTeamComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\lobby\ReturnToHubManager.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\event\PlayerGameRespawnEvent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\microbattle\MicroBattle.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\musicminecart\MusicMinecarts.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\TeamGame.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\currency\CurrencyComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\ChallengeSetCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\scoreboard\NanoScoreboard.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\world\GameWaterComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\compass\GameCompassComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\commands\game\GameCycleCommand.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\team\GameTeam.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeSlimeJump.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\components\spectator\GameSpectatorComponent.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengePunchAPig.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\games\quick\challenges\ChallengeMilkCow.java +E:\Mineplex\Mineplex\Mineplex.Game.Nano\src\mineplex\game\nano\game\GameType.java diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/plugin.yml b/Plugins[Modified]/Mineplex.Hub.Clans/plugin.yml new file mode 100644 index 00000000..1c50682b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/plugin.yml @@ -0,0 +1,3 @@ +name: ClansHub +main: mineplex.clanshub.ClansHub +version: 0.1 diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/pom.xml b/Plugins[Modified]/Mineplex.Hub.Clans/pom.xml new file mode 100644 index 00000000..8da5f3fc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + ClansHub + mineplex-clanshub + + + + ${project.groupId} + mineplex-game-clans-core + ${project.version} + + + ${project.groupId} + mineplex-minecraft-game-core + ${project.version} + + + ${project.groupId} + mineplex-clansqueue-common + ${project.version} + + + diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java new file mode 100644 index 00000000..dcfc1fb9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java @@ -0,0 +1,191 @@ +package mineplex.clanshub; + +import static mineplex.core.Managers.require; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.CustomTagFix; +import mineplex.core.PacketsInteractionFix; +import mineplex.core.account.CoreClientManager; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.antihack.AntiHack; +import mineplex.core.antihack.guardians.AntiHackGuardian; +import mineplex.core.antihack.guardians.GuardianManager; +import mineplex.core.aprilfools.AprilFoolsManager; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.boosters.BoosterManager; +import mineplex.core.chat.Chat; +import mineplex.core.command.CommandCenter; +import mineplex.core.common.events.ServerShutdownEvent; +import mineplex.core.creature.Creature; +import mineplex.core.customdata.CustomDataManager; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.elo.EloManager; +import mineplex.core.friend.FriendManager; +import mineplex.core.gadget.gadgets.particle.king.CastleManager; +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.message.MessageManager; +import mineplex.core.monitor.LagMeter; +import mineplex.core.npc.NpcManager; +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; +import mineplex.core.punish.Punish; +import mineplex.core.rankGiveaway.eternal.EternalGiveawayManager; +import mineplex.core.rankGiveaway.titangiveaway.TitanGiveawayManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.resourcepack.ResourcePackManager; +import mineplex.core.serverConfig.ServerConfiguration; +import mineplex.core.stats.StatsManager; +import mineplex.core.status.ServerStatusManager; +import mineplex.core.task.TaskManager; +import mineplex.core.teleport.Teleport; +import mineplex.core.thank.ThankManager; +import mineplex.core.titles.Titles; +import mineplex.core.titles.tracks.TrackManager; +import mineplex.core.twofactor.TwoFactorAuth; +import mineplex.core.updater.FileUpdater; +import mineplex.core.updater.Updater; +import mineplex.core.velocity.VelocityFix; +import mineplex.core.visibility.VisibilityManager; +import mineplex.core.website.WebsiteLinkManager; +import mineplex.minecraft.game.core.combat.CombatManager; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +/** + * Main class for clans hub + */ +public class ClansHub extends JavaPlugin +{ + private String WEB_CONFIG = "webServer"; + + @Override + public void onEnable() + { + Bukkit.setSpawnRadius(0); + 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 + new VelocityFix(this); + + //Static Modules + require(ProfileCacheManager.class); + CommandCenter.Initialize(this); + CoreClientManager clientManager = new CoreClientManager(this); + CommandCenter.Instance.setClientManager(clientManager); + +// new ProfileCacheManager(this); + ItemStackFactory.Initialize(this, false); + Recharge.Initialize(this); + require(VisibilityManager.class); + Give.Initialize(this); + Punish punish = new Punish(this, clientManager); + BlockRestore blockRestore = require(BlockRestore.class); + DonationManager donationManager = require(DonationManager.class); + + ServerConfiguration serverConfiguration = new ServerConfiguration(this, clientManager); + + // Publish our server status now, to give us more time to start up + ServerStatusManager serverStatusManager = new ServerStatusManager(this, clientManager, new LagMeter(this, clientManager)); + + //Other Modules + PacketHandler packetHandler = require(PacketHandler.class); + DisguiseManager disguiseManager = require(DisguiseManager.class); + IncognitoManager incognito = new IncognitoManager(this, clientManager, packetHandler); + PreferencesManager preferenceManager = new PreferencesManager(this, incognito, clientManager); + + incognito.setPreferencesManager(preferenceManager); + + Creature creature = new Creature(this); + NpcManager npcManager = new NpcManager(this, creature); + InventoryManager inventoryManager = new InventoryManager(this, clientManager); + HologramManager hologramManager = require(HologramManager.class); + CastleManager castleManager = new CastleManager(this, clientManager, hologramManager, false); + PetManager petManager = new PetManager(this, clientManager, donationManager, inventoryManager, disguiseManager, creature, blockRestore); + PollManager pollManager = new PollManager(this, clientManager, donationManager); + + //Main Modules + new TitanGiveawayManager(this, clientManager, serverStatusManager); + + Portal portal = new Portal(); + + AntiHack antiHack = require(AntiHack.class); + GuardianManager guardianManager = require(GuardianManager.class); + + for (int i = 0; i < 8; i++) + { + guardianManager.registerGuardian(new AntiHackGuardian(new Location(Bukkit.getWorld("world"), 0, 195, 0), 25, -8, 195, 185, 17, -16)); + } + + IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal); + + FriendManager friendManager = require(FriendManager.class); + + StatsManager statsManager = new StatsManager(this, clientManager); + EloManager eloManager = new EloManager(this, clientManager); + AchievementManager achievementManager = new AchievementManager(statsManager, clientManager, donationManager, incognito, eloManager); + + PartyManager partyManager = new PartyManager(); + + CustomDataManager customDataManager = require(CustomDataManager.class); + + ConditionManager condition = new ConditionManager(this); + ThankManager thankManager = new ThankManager(this, clientManager, donationManager); + BoosterManager boosterManager = new BoosterManager(this, "", clientManager, donationManager, inventoryManager, thankManager); + HubManager hubManager = new HubManager(this, blockRestore, clientManager, incognito, donationManager, inventoryManager, condition, disguiseManager, new TaskManager(this, clientManager), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, hologramManager, npcManager, packetHandler, punish, serverStatusManager, customDataManager, thankManager, boosterManager, castleManager); + + ClansTransferManager serverManager = new ClansTransferManager(this, clientManager, donationManager, partyManager, portal); + + new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, require(Chat.class)); + new MemoryFix(this); + new FileUpdater(GenericServer.CLANS_HUB); + new CustomTagFix(this, packetHandler); + new PacketsInteractionFix(this, packetHandler); + new ResourcePackManager(this, portal); + + AprilFoolsManager.getInstance(); + + new EternalGiveawayManager(this, clientManager, serverStatusManager); + + CombatManager combatManager = require(CombatManager.class); + + DamageManager damage = new DamageManager(this, combatManager, npcManager, disguiseManager, condition); + + Teleport teleport = new Teleport(this, clientManager); + + //Updates + require(Updater.class); + + require(TrackManager.class); + require(Titles.class); + require(TwoFactorAuth.class); + require(WebsiteLinkManager.class); + } + + @Override + public void onDisable() + { + getServer().getPluginManager().callEvent(new ServerShutdownEvent(this)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansServerPage.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansServerPage.java new file mode 100644 index 00000000..3e301fe9 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansServerPage.java @@ -0,0 +1,257 @@ +package mineplex.clanshub; + +import java.util.Collection; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.clanshub.queue.HubQueueManager; +import mineplex.core.Managers; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.core.stats.StatsManager; +import mineplex.game.clans.core.repository.tokens.SimpleClanToken; + +/** + * GUI page for clans servers + */ +public class ClansServerPage extends ShopPageBase +{ + private final HubQueueManager _queue = Managers.require(HubQueueManager.class); + + public ClansServerPage(ClansTransferManager plugin, ClansServerShop shop, CoreClientManager clientManager, + DonationManager donationManager, Player player) + { + super(plugin, shop, clientManager, donationManager, "Clans", player, 54); + + buildPage(); + } + + @Override + protected void buildPage() + { + if (getClientManager().Get(_player).hasPermission(ClansTransferManager.Perm.STAFF_PAGE)) + { + buildStaffJoinServers(getPlugin().Get(_player)); + } + else + { + if (!getPlugin().Get(_player).getClanName().isEmpty()) + { + buildJoinHomeServer(getPlugin().Get(_player)); + } + else + { + buildNoClanPage(); + } + } + } + + private boolean canPlayHardcore() + { + if (getClientManager().Get(_player).hasPermission(ClansTransferManager.Perm.ALLOW_HARDCORE)) + { + return true; + } + long secondsPlayed = Managers.get(StatsManager.class).Get(_player).getStat("Clans.TimePlaying"); + + return secondsPlayed >= UtilTime.convert(20, TimeUnit.HOURS, TimeUnit.SECONDS); + } + + private String timeTillUnlockHardcore() + { + if (canPlayHardcore()) + { + return "0 Seconds"; + } + else + { + long secondsPlayed = Managers.get(StatsManager.class).Get(_player).getStat("Clans.TimePlaying"); + long needed = UtilTime.convert(20, TimeUnit.HOURS, TimeUnit.SECONDS); + + return UtilTime.MakeStr(UtilTime.convert(needed - secondsPlayed, TimeUnit.SECONDS, TimeUnit.MILLISECONDS)); + } + } + + private void buildNoClanPage() + { + Collection servers = UtilAlg.sortSet(getPlugin().getServers(true), (o1, o2) -> + { + try + { + int server1; + int server2; + if (o1.Name.contains("-")) + { + server1 = Integer.parseInt(o1.Name.substring(o1.Name.lastIndexOf('-') + 1)); + } + else + { + server1 = Integer.parseInt(o1.Name); + } + if (o2.Name.contains("-")) + { + server2 = Integer.parseInt(o2.Name.substring(o2.Name.lastIndexOf('-') + 1)); + } + else + { + server2 = Integer.parseInt(o2.Name); + } + + return Integer.compare(server1, server2); + } + catch (NumberFormatException ex) + { + return o1.Name.compareTo(o2.Name); + } + }); + + int currentSlot = 9; + for (ServerInfo server : servers) + { + buildJoinServer(currentSlot, server); + currentSlot++; + } + } + + private void buildJoinHomeServer(SimpleClanToken clan) + { + ServerInfo serverInfo = getServerInfo(clan.getHomeServer()); + boolean serverOnline = (serverInfo != null); + if (!serverOnline) + { + System.out.println("Returning null"); + } + String serverStatus = serverOnline ? C.cGreen + "Online" : C.cRed + "Offline"; + + String title = (serverOnline ? C.cGreen : C.cRed) + C.Bold + "Join Home Server!"; + String serverName = C.cYellow + "Server Name: " + C.cWhite + clan.getHomeServer(); + String serverDesc = C.cYellow + "Server Status: " + C.cWhite + serverStatus; + String players = (serverOnline ? C.cYellow + "Players: " + C.cWhite + serverInfo.CurrentPlayers + "/" + serverInfo.MaxPlayers : ""); + String mode = (serverOnline ? (C.cYellow + "Mode: " + C.cWhite + (serverInfo.Hardcore ? "Hardcore" : "Casual")) : ""); + String queue1 = (serverOnline ? (C.cYellow + "Queue Status: " + (_queue.getData(serverInfo).QueuePaused ? C.cRed + "Paused" : C.cGreen + "Active")) : ""); + String queue2 = (serverOnline ? (C.cYellow + "Your Position: " + ((_queue.Get(getPlayer()).TargetServer != null && _queue.Get(getPlayer()).TargetServer.equals(serverInfo.Name)) ? (_queue.Get(getPlayer()).Queued ? C.cGreen + "#" + _queue.Get(getPlayer()).QueuePosition : C.cGray + "Joining...") : C.cGray + "Not Joined")) : ""); + String change = C.cRed + "Note: " + C.cWhite + "You must leave your Clan to "; + String change2 = C.cWhite + "play on a different Clans Server!"; + ShopItem shopItem = new ShopItem(Material.EMERALD_BLOCK, title, new String[] {" ", serverName, serverDesc, players, mode, " ", queue1, queue2, " ", change, change2, " "}, 0, true, true); + addButton(13, shopItem, new JoinServerButton(this, getServerInfo(clan.getHomeServer()))); + } + + private void buildJoinServer(int slot, ServerInfo server) + { + String title = C.cGreen + C.Bold + "Join Clans Server!"; + String desc1 = C.cYellow + "Server Name: " + C.cWhite + server.Name; + String desc2 = C.cYellow + "Players: " + C.cWhite + server.CurrentPlayers + "/" + server.MaxPlayers; + String desc3 = C.cYellow + "Mode: " + C.cWhite + (server.Hardcore ? "Hardcore" : "Casual"); + String queue1 = C.cYellow + "Queue Status: " + (_queue.getData(server).QueuePaused ? C.cRed + "Paused" : C.cGreen + "Active"); + String queue2 = C.cYellow + "Your Position: " + ((_queue.Get(getPlayer()).TargetServer != null && _queue.Get(getPlayer()).TargetServer.equals(server.Name)) ? (_queue.Get(getPlayer()).Queued ? C.cGreen + "#" + _queue.Get(getPlayer()).QueuePosition : C.cGray + "Joining...") : C.cGray + "Not Joined"); + String desc4 = ""; + String desc5 = ""; + if (!server.Hardcore || canPlayHardcore()) + { + desc4 = C.cRed + "Note: " + C.cWhite + "Creating or Joining a clan on this"; + desc5 = C.cWhite + "server will set your Home Server!"; + } + else + { + desc4 = C.cRed + "You have not unlocked Hardcore play yet!"; + desc5 = C.cWhite + "You need to play Casual for " + timeTillUnlockHardcore() + " to unlock Hardcore play!"; + } + + ShopItem shopItem = new ShopItem(Material.GOLD_BLOCK, title, new String[] {" ", desc1, desc2, desc3, " ", queue1, queue2, " ", desc4, desc5}, 0, true, true); + if (server.Hardcore && !canPlayHardcore()) + { + addButtonNoAction(slot, shopItem); + } + else + { + addButton(slot, shopItem, new JoinServerButton(this, server)); + } + } + + private void buildStaffJoinServers(SimpleClanToken clan) + { + if (!clan.getClanName().isEmpty()) + { + ServerInfo serverInfo = getServerInfo(clan.getHomeServer()); + boolean serverOnline = (serverInfo != null); + if (!serverOnline) + { + System.out.println("Returning null"); + } + String serverStatus = serverOnline ? C.cGreen + "Online" : C.cRed + "Offline"; + + String title = (serverOnline ? C.cGreen : C.cRed) + C.Bold + "Join Home Server!"; + String serverName = C.cYellow + "Server Name: " + C.cWhite + clan.getHomeServer(); + String serverDesc = C.cYellow + "Server Status: " + C.cWhite + serverStatus; + String mode = (serverOnline ? (C.cYellow + "Mode: " + C.cWhite + (serverInfo.Hardcore ? "Hardcore" : "Casual")) : ""); + String players = C.cYellow + "Players: " + C.cWhite + (serverOnline ? serverInfo.CurrentPlayers + "/" + serverInfo.MaxPlayers : "0/0"); + String queue1 = (serverOnline ? (C.cYellow + "Queue Status: " + (_queue.getData(serverInfo).QueuePaused ? C.cRed + "Paused" : C.cGreen + "Active")) : ""); + String queue2 = (serverOnline ? (C.cYellow + "Your Position: " + ((_queue.Get(getPlayer()).TargetServer != null && _queue.Get(getPlayer()).TargetServer.equals(serverInfo.Name)) ? (_queue.Get(getPlayer()).Queued ? C.cGreen + "#" + _queue.Get(getPlayer()).QueuePosition : C.cGray + "Joining...") : C.cGray + "Not Joined")) : ""); + ShopItem shopItem = new ShopItem(Material.EMERALD_BLOCK, title, new String[] {" ", serverName, serverDesc, players, mode, " ", queue1, queue2, " "}, 0, true, true); + addButton(13, shopItem, new JoinServerButton(this, getServerInfo(clan.getHomeServer()))); + } + + Collection servers = UtilAlg.sortSet(getPlugin().getServers(true), (o1, o2) -> + { + try + { + int server1; + int server2; + if (o1.Name.contains("-")) + { + server1 = Integer.parseInt(o1.Name.substring(o1.Name.lastIndexOf('-') + 1)); + } + else + { + server1 = Integer.parseInt(o1.Name); + } + if (o2.Name.contains("-")) + { + server2 = Integer.parseInt(o2.Name.substring(o2.Name.lastIndexOf('-') + 1)); + } + else + { + server2 = Integer.parseInt(o2.Name); + } + + return Integer.compare(server1, server2); + } + catch (NumberFormatException ex) + { + return o1.Name.compareTo(o2.Name); + } + }); + + int currentSlot = 27; + for (ServerInfo server : servers) + { + if (!clan.getClanName().isEmpty() && server.Name.equalsIgnoreCase(clan.getHomeServer())) + { + continue; + } + buildJoinServer(currentSlot, server); + currentSlot++; + } + } + + private ServerInfo getServerInfo(String serverName) + { + return getPlugin().getServer(serverName); + } + + /** + * Refresh all GUI pages and buttons + */ + public void update() + { + getButtonMap().clear(); + buildPage(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansServerShop.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansServerShop.java new file mode 100644 index 00000000..715f3d42 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansServerShop.java @@ -0,0 +1,43 @@ +package mineplex.clanshub; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.F; +import mineplex.core.donation.DonationManager; +import mineplex.core.party.Party; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +/** + * GUI Shop manager for clans servers + */ +public class ClansServerShop extends ShopBase +{ + public ClansServerShop(ClansTransferManager plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super(plugin, clientManager, donationManager, "Clans Servers"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new ClansServerPage(getPlugin(), this, getClientManager(), getDonationManager(), player); + } + + @Override + protected boolean canOpenShop(Player player) + { + Party party = getPlugin().getPartyManager().getPartyByPlayer(player); + + if (party != null) + { + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, .6f); + player.sendMessage(F.main("Party", "You cannot join Clans while in a party.")); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansTransferManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansTransferManager.java new file mode 100644 index 00000000..d1a8d049 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansTransferManager.java @@ -0,0 +1,275 @@ +package mineplex.clanshub; + +import java.lang.reflect.Field; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; + +import com.google.common.collect.Lists; +import com.mineplex.ProtocolVersion; + +import mineplex.clanshub.queue.HubQueueManager; +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.donation.DonationManager; +import mineplex.core.npc.event.NpcDamageByEntityEvent; +import mineplex.core.npc.event.NpcInteractEntityEvent; +import mineplex.core.party.PartyManager; +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.game.clans.core.repository.tokens.SimpleClanToken; +import mineplex.serverdata.Region; +import mineplex.serverdata.data.MinecraftServer; +import mineplex.serverdata.servers.ServerManager; + +/** + * Server selection controller for clans + */ +public class ClansTransferManager extends MiniDbClientPlugin +{ + public enum Perm implements Permission + { + STAFF_PAGE, + ALLOW_HARDCORE, + } + + private static final int[] PERMITTED_VERSIONS = {ProtocolVersion.v1_8, ProtocolVersion.v1_12, ProtocolVersion.v1_12_1, ProtocolVersion.v1_12_2}; + private static final Map VERSION_NAMES = new HashMap<>(); + + static + { + for (Field field : ProtocolVersion.class.getFields()) + { + try + { + int protocol = field.getInt(null); + String version = field.getName().replace("v", "").replace("_", "."); + + VERSION_NAMES.put(protocol, version); + } + catch (ReflectiveOperationException ex) {} + } + } + + private static final long SERVER_RELOAD_INTERVAL = 5000; + private PartyManager _party; + private Portal _portal; + private Region _region; + private final Map _servers = new HashMap<>(); + private boolean _loading = false; + private long _lastLoaded; + private ClansServerShop _serverShop; + private final HubQueueManager _queue = require(HubQueueManager.class); + + public ClansTransferManager(JavaPlugin plugin, CoreClientManager client, DonationManager donation, PartyManager party, Portal portal) + { + super("Server Transfer", plugin, client); + + _party = party; + _portal = portal; + _region = plugin.getConfig().getBoolean("serverstatus.us") ? Region.US : Region.EU; + _serverShop = new ClansServerShop(this, client, donation); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.TRAINEE.setPermission(Perm.STAFF_PAGE, true, true); + PermissionGroup.TRAINEE.setPermission(Perm.ALLOW_HARDCORE, true, true); + PermissionGroup.CONTENT.setPermission(Perm.ALLOW_HARDCORE, true, true); + } + + private boolean checkCanJoinClans(Player player) + { + int protocol = ((CraftPlayer)player).getHandle().getProtocol(); + if (ArrayUtils.contains(PERMITTED_VERSIONS, protocol)) + { + return true; + } + + UtilPlayer.message(player, F.main(getName(), "Minecraft Version " + VERSION_NAMES.get(protocol) + " is not supported on Mineplex Clans.\n" + + C.cGray + "Please change your Minecraft version to 1.8.8 or 1.12+ and reconnect!")); + + return false; + } + + /** + * Gets the stored party manager + * @return The stored party manager + */ + public PartyManager getPartyManager() + { + return _party; + } + + /** + * Gets a list of all loaded servers + * @return A list of all loaded servers + */ + public List getServers(boolean onlineOnly) + { + List servers = Lists.newArrayList(); + for (ServerInfo info : _servers.values()) + { + if (!(info.MOTD.equalsIgnoreCase("Restarting soon") || _queue.getData(info) == null) || !onlineOnly) + { + servers.add(info); + } + } + return servers; + } + + /** + * Gets the loaded ServerInfo with the given name + * @param name The name to check + * @return The loaded ServerInfo, or null if it is not stored + */ + public ServerInfo getServer(String name) + { + for (ServerInfo server : _servers.values()) + { + if (server.Name.equalsIgnoreCase(name) && !server.MOTD.equalsIgnoreCase("Restarting soon") && _queue.getData(server) != null) + { + return server; + } + } + + return null; + } + + /** + * Pulls all the clans servers from redis and loads them. SHOULD BE RUN ASYNC + */ + public void reload() + { + _servers.clear(); + for (MinecraftServer server : ServerManager.getServerRepository(_region).getServerStatusesByPrefix("Clans-")) + { + ServerInfo info = new ServerInfo(); + info.Name = server.getName(); + info.MOTD = server.getMotd(); + info.CurrentPlayers = server.getPlayerCount(); + info.MaxPlayers = server.getMaxPlayerCount(); + info.Hardcore = server.getMotd().contains("Hardcore"); + _servers.put(server, info); + } + } + + @EventHandler + public void reloadServers(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC || _loading || !UtilTime.elapsed(_lastLoaded, SERVER_RELOAD_INTERVAL)) + { + return; + } + _loading = true; + final Runnable after = () -> + { + _lastLoaded = System.currentTimeMillis(); + _loading = false; + }; + runAsync(() -> + { + reload(); + runSync(after); + }); + } + + @EventHandler + public void refreshPages(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + _serverShop.getPageMap().values().stream().filter(page -> page instanceof ClansServerPage).forEach(page -> + { + ((ClansServerPage) page).update(); + }); + } + + @EventHandler + public void onUseNPC(NpcInteractEntityEvent event) + { + if (event.getNpc().getName().contains("Clans")) + { + if (checkCanJoinClans(event.getPlayer())) + { + _serverShop.attemptShopOpen(event.getPlayer()); + } + } + if (event.getNpc().getName().contains("Return")) + { + _portal.sendToHub(event.getPlayer(), "Returning to Mineplex!", Intent.PLAYER_REQUEST); + } + } + + @EventHandler + public void onUseNPC(NpcDamageByEntityEvent event) + { + if (!(event.getDamager() instanceof Player)) + { + return; + } + Player player = (Player) event.getDamager(); + + if (event.getNpc().getName().contains("Clans") && Recharge.Instance.use(player, "Go to Clans", 1000, false, false)) + { + if (checkCanJoinClans(player)) + { + _serverShop.attemptShopOpen(player); + } + } + if (event.getNpc().getName().contains("Return") && Recharge.Instance.use(player, "Return to Mineplex", 1000, false, false)) + { + _portal.sendToHub(player, "Returning to Mineplex!", Intent.PLAYER_REQUEST); + } + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT clans.name, accountClan.clanRole, clanServer.serverName, clans.id FROM accountClan INNER JOIN clans ON clans.id = accountClan.clanId INNER JOIN clanServer ON clans.serverId = clanServer.id WHERE accountClan.accountId = " + accountId + ";"; + } + + @Override + public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException + { + SimpleClanToken clanToken = new SimpleClanToken(); + + while (resultSet.next()) + { + String clanName = resultSet.getString(1); + String clanRole = resultSet.getString(2); + String homeServer = resultSet.getString(3); + int clanId = resultSet.getInt(4); + clanToken = new SimpleClanToken(clanName, clanRole, homeServer, clanId); + } + + Set(uuid, clanToken); + } + + @Override + protected SimpleClanToken addPlayer(UUID uuid) + { + return new SimpleClanToken(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ForcefieldManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ForcefieldManager.java new file mode 100644 index 00000000..66b0077d --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ForcefieldManager.java @@ -0,0 +1,122 @@ +package mineplex.clanshub; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.preferences.Preference; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +/** + * Manager for player forcefields + */ +public class ForcefieldManager extends MiniPlugin +{ + public enum Perm implements Permission + { + BYPASS_FORCEFIELD, + FORCEFIELD_RADIUS_COMMAND, + } + + public HubManager Manager; + + private Map _radius = new HashMap<>(); + + public ForcefieldManager(HubManager manager) + { + super("Forcefield", manager.getPlugin()); + + Manager = manager; + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.BYPASS_FORCEFIELD, true, true); + PermissionGroup.EVENTMOD.setPermission(Perm.BYPASS_FORCEFIELD, false, true); + PermissionGroup.ADMIN.setPermission(Perm.FORCEFIELD_RADIUS_COMMAND, true, true); + } + + @EventHandler + public void ForcefieldUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (Manager.getPreferences().get(player).isActive(Preference.FORCE_FIELD) && Manager.GetClients().Get(player).hasPermission(Preference.FORCE_FIELD)) + { + for (Player other : UtilServer.getPlayers()) + { + if (player.equals(other)) + continue; + + int range = 5; + if (_radius.containsKey(player)) + range = _radius.get(player); + + if (UtilMath.offset(other, player) > range) + continue; + + if (Manager.GetClients().Get(other).hasPermission(Perm.BYPASS_FORCEFIELD)) + continue; + + if (Recharge.Instance.use(other, "Forcefield Bump", 500, false, false)) + { + Entity bottom = other; + while (bottom.getVehicle() != null) + bottom = bottom.getVehicle(); + + UtilAction.velocity(bottom, UtilAlg.getTrajectory2d(player, bottom), 1.6, true, 0.8, 0, 10, true); + other.getWorld().playSound(other.getLocation(), Sound.CHICKEN_EGG_POP, 2f, 0.5f); + } + } + } + } + } + + /** + * Handles the radius from a command and sets a player's forcefield to it + * @param caller The caller of the command + * @param args The args of the command + */ + public void ForcefieldRadius(Player caller, String[] args) + { + try + { + int range = Integer.parseInt(args[0]); + + _radius.put(caller, range); + + UtilPlayer.message(caller, F.main(getName(), "Radius set to " + F.elem(range + "") + ".")); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid Input. Correct input is " + F.elem("/radius #") + ".")); + } + } + + @EventHandler + public void ForcefieldReset(PlayerQuitEvent event) + { + _radius.remove(event.getPlayer()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubManager.java new file mode 100644 index 00000000..6c50df52 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubManager.java @@ -0,0 +1,972 @@ +package mineplex.clanshub; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.Egg; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerVelocityEvent; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.clanshub.commands.ForcefieldRadius; +import mineplex.clanshub.commands.GadgetToggle; +import mineplex.clanshub.commands.GameModeCommand; +import mineplex.clanshub.profile.gui.GUIProfile; +import mineplex.clanshub.salesannouncements.SalesAnnouncementManager; +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.benefit.BenefitManager; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.boosters.BoosterManager; +import mineplex.core.botspam.BotSpamManager; +import mineplex.core.chat.Chat; +import mineplex.core.chat.ChatFormat; +import mineplex.core.chat.format.LevelFormatComponent; +import mineplex.core.chat.format.RankFormatComponent; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTextTop; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.communities.CommunityManager; +import mineplex.core.cosmetic.CosmeticManager; +import mineplex.core.customdata.CustomDataManager; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.disguise.disguises.DisguiseBase; +import mineplex.core.disguise.disguises.DisguiseWither; +import mineplex.core.donation.DonationManager; +import mineplex.core.donation.Donor; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.event.GadgetCollideEntityEvent; +import mineplex.core.gadget.gadgets.morph.MorphWither; +import mineplex.core.gadget.gadgets.mount.types.MountDragon; +import mineplex.core.gadget.gadgets.particle.king.CastleManager; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.hologram.HologramManager; +import mineplex.core.incognito.IncognitoManager; +import mineplex.core.incognito.events.IncognitoHidePlayerEvent; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.menu.MenuManager; +import mineplex.core.message.PrivateMessageEvent; +import mineplex.core.notifier.NotificationManager; +import mineplex.core.npc.NpcManager; +import mineplex.core.packethandler.PacketHandler; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.personalServer.PersonalServerManager; +import mineplex.core.pet.PetManager; +import mineplex.core.playerCount.PlayerCountManager; +import mineplex.core.poll.PollManager; +import mineplex.core.portal.GenericServer; +import mineplex.core.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.core.preferences.Preference; +import mineplex.core.preferences.PreferencesManager; +import mineplex.core.punish.Punish; +import mineplex.core.scoreboard.MineplexScoreboard; +import mineplex.core.scoreboard.ScoreboardManager; +import mineplex.core.scoreboard.TabListSorter; +import mineplex.core.stats.StatsManager; +import mineplex.core.status.ServerStatusManager; +import mineplex.core.task.TaskManager; +import mineplex.core.thank.ThankManager; +import mineplex.core.treasure.TreasureManager; +import mineplex.core.twofactor.TwoFactorAuth; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.youtube.YoutubeManager; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; +import mineplex.minecraft.game.core.condition.ConditionManager; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.HoverEvent.Action; +import net.md_5.bungee.api.chat.TextComponent; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.EntityPlayer; + +/** + * Main manager for clans hub + */ +public class HubManager extends MiniPlugin +{ + public enum Perm implements Permission + { + GADGET_TOGGLE_COMMAND, + GAMEMODE_COMMAND, + AUTO_OP, + VANISH, + SPAWN_PM, + JOIN_FULL, + } + + private BlockRestore _blockRestore; + private CoreClientManager _clientManager; + private ConditionManager _conditionManager; + private DonationManager _donationManager; + private DisguiseManager _disguiseManager; + private PartyManager _partyManager; + private ForcefieldManager _forcefieldManager; + private PollManager _pollManager; + private Portal _portal; + private StatsManager _statsManager; + private GadgetManager _gadgetManager; + private HubVisibilityManager _visibilityManager; + private PreferencesManager _preferences; + private InventoryManager _inventoryManager; + private AchievementManager _achievementManager; + private TreasureManager _treasureManager; + private PetManager _petManager; + private PacketHandler _packetHandler; + private PlayerCountManager _playerCountManager; + private CustomDataManager _customDataManager; + private Punish _punishManager; + private IncognitoManager _incognito; + private BonusManager _bonusManager; + private final TwoFactorAuth _twofactor = Managers.require(TwoFactorAuth.class); + + private Location _spawn; + + private String _serverName = ""; + private boolean _shuttingDown; + + private Map _portalTime = new HashMap<>(); + + private Map> _creativeAdmin = new HashMap<>(); + + public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, IncognitoManager incognito, DonationManager donationManager, InventoryManager inventoryManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PacketHandler packetHandler, Punish punish, ServerStatusManager serverStatusManager, CustomDataManager customDataManager, ThankManager thankManager, BoosterManager boosterManager, CastleManager castleManager) + { + super("Hub Manager", plugin); + + _incognito = incognito; + + _blockRestore = blockRestore; + _clientManager = clientManager; + _conditionManager = conditionManager; + _donationManager = donationManager; + _disguiseManager = disguiseManager; + _pollManager = pollManager; + + _portal = portal; + + _spawn = new Location(UtilWorld.getWorld("world"), 0.5, 179, 0.5, -90f, 0f); + ((CraftWorld) _spawn.getWorld()).getHandle().spigotConfig.itemMerge = 0; + + new WorldManager(this); + _inventoryManager = inventoryManager; + new BenefitManager(plugin, clientManager, _inventoryManager); + + _gadgetManager = require(GadgetManager.class); + achievementManager.setGadgetManager(_gadgetManager); + + YoutubeManager youtubeManager = new YoutubeManager(plugin, clientManager, donationManager); + _bonusManager = new BonusManager(plugin, null, clientManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager, youtubeManager, _gadgetManager, thankManager, "Carter"); + + World world = _spawn.getWorld(); + _treasureManager = require(TreasureManager.class); + _treasureManager.addTreasureLocation(new Location(world, -0.5, 179, -8.5)); + _treasureManager.addTreasureLocation(new Location(world, -0.5, 179, 9.5)); + + new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, petManager, _treasureManager, boosterManager, punish); + + new MenuManager(_plugin); + require(Chat.class).setFormatComponents( + new LevelFormatComponent(achievementManager), + new RankFormatComponent(clientManager), + player -> + { + TextComponent component = new TextComponent(player.getName()); + component.setColor(net.md_5.bungee.api.ChatColor.YELLOW); + return component; + } + ); + + _petManager = petManager; + _partyManager = partyManager; + _preferences = preferences; + _visibilityManager = new HubVisibilityManager(this); + + _forcefieldManager = new ForcefieldManager(this); + addCommand(new ForcefieldRadius(_forcefieldManager)); + + _statsManager = statsManager; + _achievementManager = achievementManager; + _packetHandler = packetHandler; + + new NotificationManager(getPlugin(), clientManager); + new BotSpamManager(plugin, clientManager, punish); + + ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; + + //new ValentinesGiftManager(plugin, clientManager, _bonusManager.getRewardManager(), inventoryManager, _gadgetManager, statsManager); + + _playerCountManager = new PlayerCountManager(plugin); + + _customDataManager = Managers.get(CustomDataManager.class); + + _punishManager = punish; + + _serverName = getPlugin().getConfig().getString("serverstatus.name"); + _serverName = _serverName.substring(0, Math.min(16, _serverName.length())); + + new SalesAnnouncementManager(plugin); + + require(PersonalServerManager.class); + require(CommunityManager.class); + require(TabListSorter.class); + ScoreboardManager scoreboardManager = new ScoreboardManager(plugin) + { + @Override + public void setup(MineplexScoreboard scoreboard) + { + for (PermissionGroup group : PermissionGroup.values()) + { + if (!group.canBePrimary()) + { + continue; + } + if (!group.getDisplay(false, false, false, false).isEmpty()) + { + scoreboard.getHandle().registerNewTeam(group.name()).setPrefix(group.getDisplay(true, true, true, false) + ChatColor.RESET + " "); + } + else + { + scoreboard.getHandle().registerNewTeam(group.name()).setPrefix(""); + } + } + + scoreboard.register(HubScoreboardLine.START_EMPTY_SPACER) + .register(HubScoreboardLine.SERVER_TITLE) + .register(HubScoreboardLine.SERVER_NAME) + .register(HubScoreboardLine.SERVER_EMPTY_SPACER) + .register(HubScoreboardLine.PLAYER_TITLE) + .register(HubScoreboardLine.PLAYER_COUNT) + .register(HubScoreboardLine.PLAYER_EMPTY_SPACER) + .register(HubScoreboardLine.RANK_TITLE) + .register(HubScoreboardLine.RANK_NAME) + .register(HubScoreboardLine.RANK_EMPTY_SPACER) + .register(HubScoreboardLine.WEBSITE_TITLE) + .register(HubScoreboardLine.WEBSITE_VALUE) + .recalculate(); + + scoreboard.get(HubScoreboardLine.SERVER_TITLE).write(C.cAqua + C.Bold + "Server"); + scoreboard.get(HubScoreboardLine.SERVER_NAME).write(_serverName); + scoreboard.get(HubScoreboardLine.PLAYER_TITLE).write(C.cYellow + C.Bold + "Players"); + scoreboard.get(HubScoreboardLine.RANK_TITLE).write(C.cGold + C.Bold + "Rank"); + scoreboard.get(HubScoreboardLine.WEBSITE_TITLE).write(C.cRed + C.Bold + "Website"); + scoreboard.get(HubScoreboardLine.WEBSITE_VALUE).write("www.mineplex.com"); + } + + @Override + public void draw(MineplexScoreboard scoreboard) + { + scoreboard.setSidebarName(C.cRed + C.Bold + C.Line + "Mineplex Clans"); + scoreboard.get(HubScoreboardLine.PLAYER_COUNT).write(_playerCountManager.getPlayerCount()); + + String rankName = getRankName(GetClients().Get(scoreboard.getOwner()).getPrimaryGroup(), GetDonation().Get(scoreboard.getOwner())); + + PermissionGroup disguisedRank = GetClients().Get(scoreboard.getOwner()).getDisguisedPrimaryGroup(); + String disguisedAs = GetClients().Get(scoreboard.getOwner()).getDisguisedAs(); + if (disguisedRank != null && disguisedAs != null) + { + rankName = getRankName(disguisedRank, GetDonation().Get(GetClients().Get(scoreboard.getOwner()).getDisguisedAsUUID())) + " (" + rankName + ")"; + } + + scoreboard.get(HubScoreboardLine.RANK_NAME).write(rankName); + } + + @Override + public void handlePlayerJoin(String playerName) + { + Player player = Bukkit.getPlayerExact(playerName); + + PermissionGroup group = _clientManager.Get(player).getRealOrDisguisedPrimaryGroup(); + + for (MineplexScoreboard scoreboard : getScoreboards().values()) + { + scoreboard.getHandle().getTeam(group.name()).addEntry(playerName); + } + + if (get(player) != null) + { + for (Player player1 : Bukkit.getOnlinePlayers()) + { + group = _clientManager.Get(player1).getRealOrDisguisedPrimaryGroup(); + get(player).getHandle().getTeam(group.name()).addEntry(player1.getName()); + } + } + } + + @Override + public void handlePlayerQuit(String playerName) + { + Player player = Bukkit.getPlayerExact(playerName); + + PermissionGroup group = _clientManager.Get(player).getRealOrDisguisedPrimaryGroup(); + + for (MineplexScoreboard scoreboard : getScoreboards().values()) + { + scoreboard.getHandle().getTeam(group.name()).removeEntry(playerName); + } + } + + private String getRankName(PermissionGroup group, Donor donor) + { + String display = group.getDisplay(false, false, false, false); + if (display.isEmpty()) + { + if (donor.ownsUnknownSalesPackage("SuperSmashMobs ULTRA") || + donor.ownsUnknownSalesPackage("Survival Games ULTRA") || + donor.ownsUnknownSalesPackage("Minigames ULTRA") || + donor.ownsUnknownSalesPackage("CastleSiege ULTRA") || + donor.ownsUnknownSalesPackage("Champions ULTRA")) + { + display = "Single Ultra"; + } + else + { + display = "No Rank"; + } + } + + return display; + } + }; + + Managers.put(scoreboardManager, ScoreboardManager.class); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.GADGET_TOGGLE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.GAMEMODE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.AUTO_OP, true, true); + if (UtilServer.isTestServer()) + { + PermissionGroup.QAM.setPermission(Perm.AUTO_OP, false, true); + } + PermissionGroup.CMOD.setPermission(Perm.VANISH, false, true); + PermissionGroup.ADMIN.setPermission(Perm.VANISH, true, true); + PermissionGroup.TRAINEE.setPermission(Perm.SPAWN_PM, true, true); + PermissionGroup.ULTRA.setPermission(Perm.JOIN_FULL, true, true); + } + + @Override + public void addCommands() + { + addCommand(new GadgetToggle(this)); + addCommand(new GameModeCommand(this)); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void reflectMotd(ServerListPingEvent event) + { + if (_shuttingDown) + { + event.setMotd("Restarting soon"); + } + } + + @EventHandler + public void redirectStopCommand(PlayerCommandPreprocessEvent event) + { + if (event.getPlayer().isOp() && event.getMessage().equalsIgnoreCase("/stop")) + { + _shuttingDown = true; + + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable() + { + public void run() + { + _portal.sendAllPlayersToGenericServer(GenericServer.HUB, Intent.KICK); + + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(_plugin, new Runnable() + { + public void run() + { + Bukkit.shutdown(); + } + }, 40L); + } + }, 60L); + + event.setCancelled(true); + } + } + + @EventHandler + public void preventEggSpawn(ItemSpawnEvent event) + { + if (event.getEntity() instanceof Egg) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void login(final PlayerLoginEvent event) + { + CoreClient client = _clientManager.Get(event.getPlayer()); + + // Reserved Slot Check + if (Bukkit.getOnlinePlayers().size() - Bukkit.getServer().getMaxPlayers() >= 20) + { + if (!client.hasPermission(Perm.JOIN_FULL)) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> + { + _portal.sendPlayerToGenericServer(event.getPlayer(), GenericServer.CLANS_HUB, Intent.KICK); + }); + + event.allow(); + } + } + else + { + event.allow(); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void handleOP(PlayerJoinEvent event) + { + if (_clientManager.Get(event.getPlayer()).hasPermission(Perm.AUTO_OP)) + { + event.getPlayer().setOp(true); + } else + { + event.getPlayer().setOp(false); + } + } + + @EventHandler + public void PlayerRespawn(PlayerRespawnEvent event) + { + event.setRespawnLocation(GetSpawn()); + } + + @EventHandler(priority = EventPriority.LOW) + public void PlayerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + + //Public Message + event.setJoinMessage(null); + + //Teleport + player.teleport(GetSpawn()); + + //Survival + player.setGameMode(GameMode.SURVIVAL); + + //Clear Inv + UtilInv.Clear(player); + + //Health + player.setHealth(20); + } + + @EventHandler + public void PlayerQuit(PlayerQuitEvent event) + { + event.setQuitMessage(null); + + event.getPlayer().leaveVehicle(); + event.getPlayer().eject(); + event.getPlayer().setOp(false); + + _portalTime.remove(event.getPlayer().getName()); + } + + @EventHandler + public void playerPrivateMessage(PrivateMessageEvent event) + { + //Dont Let PM Near Spawn! + if (UtilMath.offset2d(GetSpawn(), event.getSender().getLocation()) == 0 && !_clientManager.Get(event.getSender()).hasPermission(Perm.SPAWN_PM)) + { + UtilPlayer.message(event.getSender(), F.main("Chat", "You must leave spawn before you can Private Message!")); + event.setCancelled(true); + } + } + + @EventHandler + public void Incog(IncognitoHidePlayerEvent event) + { + if (!_clientManager.Get(event.getPlayer()).hasPermission(Perm.VANISH)) + { + event.setCancelled(true); + } + } + + @EventHandler(ignoreCancelled = true) + public void playerChat(AsyncPlayerChatEvent event) + { + //Don't Let Chat Near Spawn! + if (UtilMath.offset2dSquared(GetSpawn(), event.getPlayer().getLocation()) == 0 && !_clientManager.Get(event.getPlayer()).hasPermission(Perm.SPAWN_PM)) + { + UtilPlayer.message(event.getPlayer(), F.main("Chat", "You must leave spawn before you can chat!")); + event.setCancelled(true); + } + } + + @EventHandler + public void Damage(EntityDamageEvent event) + { + if (event.getCause() == DamageCause.VOID) + { + if (event.getEntity() instanceof Player) + { + event.getEntity().eject(); + event.getEntity().leaveVehicle(); + event.getEntity().teleport(GetSpawn()); + } + else + { + event.getEntity().remove(); + } + } + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void handleDeath(PlayerDeathEvent event) + { + event.setKeepInventory(true); + event.getDrops().clear(); + event.getEntity().setHealth(20); + event.getEntity().teleport(GetSpawn()); + } + + @EventHandler + public void combatDeath(CombatDeathEvent event) + { + event.SetBroadcastType(DeathMessageType.None); + } + + @EventHandler + public void FoodHealthUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Player player : UtilServer.getPlayers()) + { + player.setFoodLevel(20); + player.setExhaustion(0f); + player.setSaturation(3f); + } + } + + @EventHandler + public void InventoryCancel(InventoryClickEvent event) + { + if (event.getWhoClicked() instanceof Player && ((Player)event.getWhoClicked()).getGameMode() != GameMode.CREATIVE) + event.setCancelled(true); + } + + @EventHandler + public void UpdateDisplay(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + Bukkit.getOnlinePlayers().stream().filter(player -> _clientManager.Get(player).getPrimaryGroup() == PermissionGroup.PLAYER).forEach(player -> + { + UtilTextBottom.display(C.cGray + "Visit " + F.elem("http://www.mineplex.com/shop") + " for exclusive perks!", player); + }); + } + + /** + * Gets the loaded BlockRestore manager + * @return The loaded BlockRestore manager + */ + public BlockRestore GetBlockRestore() + { + return _blockRestore; + } + + /** + * Gets the loaded CoreClient manager + * @return The loaded CoreClient manager + */ + public CoreClientManager GetClients() + { + return _clientManager; + } + + /** + * Gets the loaded Condition manager + * @return The loaded Condition manager + */ + public ConditionManager GetCondition() + { + return _conditionManager; + } + + /** + * Gets the loaded Donation manager + * @return The loaded Donation manager + */ + public DonationManager GetDonation() + { + return _donationManager; + } + + /** + * Gets the loaded Disguise manager + * @return The loaded Disguise manager + */ + public DisguiseManager GetDisguise() + { + return _disguiseManager; + } + + /** + * Gets the loaded Gadget manager + * @return The loaded Gadget manager + */ + public GadgetManager GetGadget() + { + return _gadgetManager; + } + + /** + * Gets the loaded Treasure manager + * @return The loaded Treasure manager + */ + public TreasureManager GetTreasure() + { + return _treasureManager; + } + + /** + * Gets the loaded Preferences manager + * @return The loaded Preferences manager + */ + public PreferencesManager getPreferences() + { + return _preferences; + } + + /** + * Gets the lobby's spawn + * @return The lobby's spawn + */ + public Location GetSpawn() + { + return _spawn.clone(); + } + + /** + * Gets the loaded Pet manager + * @return The loaded Pet manager + */ + public PetManager getPetManager() + { + return _petManager; + } + + /** + * Gets the loaded Bonus manager + * @return The loaded Bonus manager + */ + public BonusManager getBonusManager() + { + return _bonusManager; + } + + /** + * Gets the loaded Stats manager + * @return The loaded Stats manager + */ + public StatsManager GetStats() + { + return _statsManager; + } + + /** + * Gets the loaded HubVisibility manager + * @return The loaded HubVisibility manager + */ + public HubVisibilityManager GetVisibility() + { + return _visibilityManager; + } + + /** + * Gets the loaded CustomData manager + * @return The loaded CustomData manager + */ + public CustomDataManager getCustomDataManager() + { + return _customDataManager; + } + + /** + * Gets the loaded Punishment manager + * @return The loaded Punishment manager + */ + public Punish getPunishments() + { + return _punishManager; + } + + /** + * Gets the loaded Incognito manager + * @return The loaded Incognito manager + */ + public IncognitoManager getIncognitoManager() + { + return _incognito; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void gadgetCollide(GadgetCollideEntityEvent event) + { + if (!event.isCancelled()) + { + SetPortalDelay(event.getEntity()); + } + } + + /** + * Updates a player's portal delay start to be now + * @param ent The player to set delay for + */ + public void SetPortalDelay(Entity ent) + { + if (ent instanceof Player) + { + _portalTime.put(((Player)ent).getName(), System.currentTimeMillis()); + } + } + + /** + * Checks if a player can portal yet + * @param player The player to check + * @return Whether a player can portal yet + */ + public boolean CanPortal(Player player) + { + //Riding + if (player.getVehicle() != null || player.getPassenger() != null) + return false; + + //Portal Delay + if (!_portalTime.containsKey(player.getName())) + return true; + + return UtilTime.elapsed(_portalTime.get(player.getName()), 5000); + } + + @EventHandler + public void ignoreVelocity(PlayerVelocityEvent event) + { + if (_clientManager.Get(event.getPlayer()).hasPermission(Preference.IGNORE_VELOCITY) && _preferences.get(event.getPlayer()).isActive(Preference.IGNORE_VELOCITY)) + { + event.setCancelled(true); + } + } + + /** + * Toggles all gadgets on or off via command + * @param caller The player who issued the command + */ + public void ToggleGadget(Player caller) + { + toggleGadget(); + } + + /** + * Toggles gadget access on or off in this lobby + */ + public void toggleGadget() + { + GetGadget().toggleGadgetEnabled(); + + for (Player player : UtilServer.getPlayers()) + player.sendMessage(C.cWhite + C.Bold + "Gadgets/Mounts are now " + F.elem(GetGadget().isGadgetEnabled() ? C.cGreen + C.Bold + "Enabled" : C.cRed + C.Bold + "Disabled")); + } + + /** + * Sets a player's gamemode via command + * @param caller The issuer of the command + * @param target The player whose gamemode should be set + */ + public void addGameMode(Player caller, Player target) + { + if (!_creativeAdmin.containsKey(caller.getName())) + _creativeAdmin.put(caller.getName(), new ArrayList()); + + if (target.getGameMode() == GameMode.CREATIVE) + { + _creativeAdmin.get(caller.getName()).add(target.getName()); + } + else + { + _creativeAdmin.get(caller.getName()).remove(target.getName()); + } + } + + @EventHandler + public void clearEntityTargets(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Entity entity : Bukkit.getWorlds().get(0).getEntities()) + { + if (entity instanceof EntityInsentient) + { + EntityInsentient entityMonster = (EntityInsentient)entity; + + if (entityMonster.getGoalTarget() != null && entityMonster.getGoalTarget() instanceof EntityPlayer) + { + if (((EntityPlayer)entityMonster.getGoalTarget()).playerConnection.isDisconnected()) + entityMonster.setGoalTarget(null, TargetReason.FORGOT_TARGET, false); + } + } + } + } + + @EventHandler + public void clearGameMode(PlayerQuitEvent event) + { + List creative = _creativeAdmin.remove(event.getPlayer().getName()); + + if (creative == null) + return; + + for (String name : creative) + { + Player player = UtilPlayer.searchExact(name); + if (player == null) + continue; + + player.setGameMode(GameMode.SURVIVAL); + + UtilPlayer.message(player, F.main("Game Mode", event.getPlayer().getName() + " left the game. Creative Mode: " + F.tf(false))); + } + } + + /** + * Gets the loaded PacketHandler + * @return The loaded PacketHandler + */ + public PacketHandler getPacketHandler() + { + return _packetHandler; + } + + @EventHandler + public void openProfile(PlayerInteractEvent event) + { + if(_twofactor.isAuthenticating(event.getPlayer()) || event.getItem() == null || event.getItem().getType() != Material.SKULL_ITEM) + return; + + new GUIProfile(getPlugin(), event.getPlayer(), _preferences, _achievementManager).openInventory();; + } + + @EventHandler + public void trackPortalDelayPlayers(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + for (Iterator playerNameIterator = _portalTime.keySet().iterator(); playerNameIterator.hasNext();) + { + String playerName = playerNameIterator.next(); + + if (UtilTime.elapsed(_portalTime.get(playerName), 5000)) + { + playerNameIterator.remove(); + } + } + } + + @EventHandler + public void showHeader(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTEST) + { + return; + } + + String text = C.cRed + "Welcome to Mineplex Clans"; + UtilTextTop.display(text, UtilServer.getPlayers()); + + //Fix Entity Names + for (Entity pet : _petManager.getPets()) + { + if (pet instanceof LivingEntity) + { + DisguiseBase disguise = _disguiseManager.getActiveDisguise((LivingEntity) pet); + + if (disguise instanceof DisguiseWither) + { + ((DisguiseWither) disguise).setName(text); + disguise.resendMetadata(); + } + } + } + + for (Gadget mount : _gadgetManager.getGadgets(GadgetType.MOUNT)) + { + if (mount instanceof MountDragon) + { + ((MountDragon)mount).SetName(text); + } + } + + for (Gadget gadget : _gadgetManager.getGadgets(GadgetType.MORPH)) + { + if (gadget instanceof MorphWither) + { + ((MorphWither)gadget).setWitherData(text, 100); + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubScoreboardLine.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubScoreboardLine.java new file mode 100644 index 00000000..4d68ebeb --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubScoreboardLine.java @@ -0,0 +1,19 @@ +package mineplex.clanshub; + +import mineplex.core.scoreboard.ScoreboardLine; + +public enum HubScoreboardLine implements ScoreboardLine +{ + START_EMPTY_SPACER, + SERVER_TITLE, + SERVER_NAME, + SERVER_EMPTY_SPACER, + PLAYER_TITLE, + PLAYER_COUNT, + PLAYER_EMPTY_SPACER, + RANK_TITLE, + RANK_NAME, + RANK_EMPTY_SPACER, + WEBSITE_TITLE, + WEBSITE_VALUE; +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubVisibilityManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubVisibilityManager.java new file mode 100644 index 00000000..3946b836 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/HubVisibilityManager.java @@ -0,0 +1,107 @@ +package mineplex.clanshub; + +import java.util.HashSet; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.preferences.Preference; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.visibility.VisibilityManager; + +/** + * Manager for Hub Visibility of players + */ +public class HubVisibilityManager extends MiniPlugin +{ + public enum Perm implements Permission + { + BYPASS_INVISIBILITY, + } + + public HubManager Manager; + + private HashSet _hiddenPlayers = new HashSet(); + + public HubVisibilityManager(HubManager manager) + { + super("Visibility Manager", manager.getPlugin()); + + Manager = manager; + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.MOD.setPermission(Perm.BYPASS_INVISIBILITY, true, true); + } + + /** + * Force sets a player as hidden + * @param player The player to set + */ + public void addHiddenPlayer(Player player) + { + _hiddenPlayers.add(player); + + } + + /** + * Force unsets a player as hidden + * @param player The player to unset + */ + public void removeHiddenPlayer(Player player) + { + _hiddenPlayers.remove(player); + } + + @EventHandler + public void removeHiddenPlayerOnQuit(PlayerQuitEvent event) + { + _hiddenPlayers.remove(event.getPlayer()); + } + + @EventHandler + public void updateVisibility(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + VisibilityManager vm = Managers.get(VisibilityManager.class); + + for (Player player : UtilServer.getPlayers()) + { + boolean hideMe = UtilMath.offset2d(player.getLocation(), Manager.GetSpawn()) == 0 || + (Manager.getPreferences().get(player).isActive(Preference.INVISIBILITY) && Manager.GetClients().Get(player).hasPermission(Preference.INVISIBILITY)) || + _hiddenPlayers.contains(player); + + for (Player other : UtilServer.getPlayers()) + { + boolean localHideMe = hideMe; + if (player.equals(other)) + continue; + + if (Manager.GetClients().Get(other).hasPermission(Perm.BYPASS_INVISIBILITY)) + localHideMe = false; + + if (localHideMe || !Manager.getPreferences().get(other).isActive(Preference.SHOW_PLAYERS)) + { + vm.hidePlayer(other, player, "Hub Visibility Manager"); + } + else + { + vm.showPlayer(other, player, "Hub Visibility Manager"); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/JoinServerButton.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/JoinServerButton.java new file mode 100644 index 00000000..b36467ec --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/JoinServerButton.java @@ -0,0 +1,55 @@ +package mineplex.clanshub; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.clanshub.queue.HubQueueManager; +import mineplex.core.Managers; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.page.ShopPageBase; + +/** + * GUI button to select a server from a display + */ +public class JoinServerButton implements IButton +{ + private ShopPageBase _page; + private ServerInfo _serverInfo; + private final HubQueueManager _queue = Managers.require(HubQueueManager.class); + + public JoinServerButton(ShopPageBase page, ServerInfo serverInfo) + { + _page = page; + _serverInfo = serverInfo; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + selectServer(player, _serverInfo); + } + + /** + * Selects a server to send a player to + * @param player The player to send + * @param serverInfo The server to send the player to + */ + public void selectServer(Player player, ServerInfo serverInfo) + { + if (serverInfo != null) + { + if (_queue.Get(player).TargetServer == null || !_queue.Get(player).TargetServer.equals(serverInfo.Name)) + { + _queue.attemptEnterQueue(player, _queue.getData(serverInfo)); + } + else + { + _queue.leaveQueue(player, true); + } + } + else + { + _page.playDenySound(player); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ServerInfo.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ServerInfo.java new file mode 100644 index 00000000..1dc44860 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/ServerInfo.java @@ -0,0 +1,22 @@ +package mineplex.clanshub; + +/** + * Data class for loaded servers + */ +public class ServerInfo +{ + public String Name; + public String MOTD; + public int CurrentPlayers = 0; + public int MaxPlayers = 0; + public boolean Hardcore = false; + + /** + * Checks how many slots are left on this server + * @return The amount of slots that are left on this server + */ + public int getAvailableSlots() + { + return MaxPlayers - CurrentPlayers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/WorldManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/WorldManager.java new file mode 100644 index 00000000..577bbb7e --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/WorldManager.java @@ -0,0 +1,211 @@ +package mineplex.clanshub; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.weather.WeatherChangeEvent; + +/** + * Manager for the hub world + */ +public class WorldManager extends MiniPlugin +{ + public HubManager Manager; + + public WorldManager(HubManager manager) + { + super("World Manager", manager.getPlugin()); + + Manager = manager; + + World world = UtilWorld.getWorld("world"); + + world.setGameRuleValue("doDaylightCycle", "false"); + + world.setTime(6000); + world.setStorm(false); + world.setThundering(false); + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) + return; + + event.setCancelled(true); + } + + @EventHandler + public void onBlockBurn(BlockBurnEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onBlockIgnite(BlockIgniteEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onEntityChangeBlock(EntityChangeBlockEvent event) + { + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onExplosion(EntityExplodeEvent event) + { + event.blockList().clear(); + } + + @EventHandler + public void onVineGrow(BlockSpreadEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onLeafDecay(LeavesDecayEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) + return; + + event.setCancelled(true); + } + + @EventHandler + public void onBorderUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTEST) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (UtilMath.offset(player.getLocation(), Manager.GetSpawn()) > 50) + { + player.eject(); + player.leaveVehicle(); + player.teleport(Manager.GetSpawn()); + } + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onItemPickup(PlayerPickupItemEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) + return; + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW) + public void onItemDrop(PlayerDropItemEvent event) + { + if (event.getPlayer().getGameMode() == GameMode.CREATIVE) + return; + + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOW) + public void onItemDespawn(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Entity ent : UtilWorld.getWorld("world").getEntities()) + { + if (!(ent instanceof Item)) + continue; + + if (((Item)ent).getItemStack().getType() == Material.MONSTER_EGG) + continue; + + if (UtilEnt.GetMetadata(ent, "UtilItemSpawning") != null) + continue; + + if (ent.getTicksLived() > 1200) + ent.remove(); + } + } + + @EventHandler + public void onWeather(WeatherChangeEvent event) + { + if (!event.getWorld().getName().equals("world")) + return; + + event.setCancelled(true); + } + + @EventHandler + public void onBlockForm(BlockFormEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onBoatBreak(CustomDamageEvent event) + { + if (event.GetDamageeEntity() instanceof Boat) + { + event.SetCancelled("Boat Cancel"); + } + } + + @EventHandler + public void prevenCombustiont(EntityCombustEvent event) + { + if (event.getEntity() instanceof Player) + { + event.setCancelled(true); + } + } + + @EventHandler + public void preventMobs(CreatureSpawnEvent event) + { + if (event.getSpawnReason() == SpawnReason.NATURAL || event.getSpawnReason() == SpawnReason.NETHER_PORTAL) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/ForcefieldRadius.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/ForcefieldRadius.java new file mode 100644 index 00000000..6d5b5b8a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/ForcefieldRadius.java @@ -0,0 +1,23 @@ +package mineplex.clanshub.commands; + +import org.bukkit.entity.Player; + +import mineplex.clanshub.ForcefieldManager; +import mineplex.core.command.CommandBase; + +/** + * Command for controlling forcefield radius + */ +public class ForcefieldRadius extends CommandBase +{ + public ForcefieldRadius(ForcefieldManager plugin) + { + super(plugin, ForcefieldManager.Perm.FORCEFIELD_RADIUS_COMMAND, "radius", "forcefield"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.ForcefieldRadius(caller, args); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/GadgetToggle.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/GadgetToggle.java new file mode 100644 index 00000000..45c8e9da --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/GadgetToggle.java @@ -0,0 +1,23 @@ +package mineplex.clanshub.commands; + +import org.bukkit.entity.Player; + +import mineplex.clanshub.HubManager; +import mineplex.core.command.CommandBase; + +/** + * Command for toggling gadgets + */ +public class GadgetToggle extends CommandBase +{ + public GadgetToggle(HubManager plugin) + { + super(plugin, HubManager.Perm.GADGET_TOGGLE_COMMAND, "gadget"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Plugin.ToggleGadget(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/GameModeCommand.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/GameModeCommand.java new file mode 100644 index 00000000..74b03d46 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/commands/GameModeCommand.java @@ -0,0 +1,51 @@ +package mineplex.clanshub.commands; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +import mineplex.clanshub.HubManager; +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; + +/** + * Command for setting gamemode + */ +public class GameModeCommand extends CommandBase +{ + public GameModeCommand(HubManager plugin) + { + super(plugin, HubManager.Perm.GAMEMODE_COMMAND, "gamemode", "gm"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Player target = caller; + + if (args != null && args.length >= 1) + { + target = UtilPlayer.searchOnline(caller, args[0], true); + + if (target == null) + return; + } + + if (target.getGameMode() == GameMode.SURVIVAL) + { + target.setGameMode(GameMode.CREATIVE); + } + else + { + target.setGameMode(GameMode.SURVIVAL); + } + + if (!target.equals(caller)) + { + Plugin.addGameMode(caller, target); + UtilPlayer.message(target, F.main("Game Mode", caller.getName() + " toggled your Creative Mode: " + F.tf(target.getGameMode() == GameMode.CREATIVE))); + } + + UtilPlayer.message(caller, F.main("Game Mode", target.getName() + " Creative Mode: " + F.tf(target.getGameMode() == GameMode.CREATIVE))); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/buttons/ButtonPrefs.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/buttons/ButtonPrefs.java new file mode 100644 index 00000000..54b195ef --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/buttons/ButtonPrefs.java @@ -0,0 +1,58 @@ +package mineplex.clanshub.profile.buttons; + +import mineplex.clanshub.profile.gui.GUIProfile; +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemBuilder; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Button to open preferences menu + */ +public class ButtonPrefs implements GuiItem +{ + private GUIProfile _profile; + private Player _player; + + public ButtonPrefs(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getPrefManager().openMenu(_player); + } + + @Override + public ItemStack getObject() + { + return new ItemBuilder(Material.REDSTONE_COMPARATOR).setTitle(C.Reset + C.cYellow + "Preferences").addLore(new String[] + { + "", + C.cWhite + "Set your preferences to your liking", + C.cWhite + "so you can enjoy the game more!", + + "", + C.cWhite + "Type " + C.cGreen + "/prefs" + C.cWhite + " to access this anywhere!" + }).build(); + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/buttons/ButtonStats.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/buttons/ButtonStats.java new file mode 100644 index 00000000..4b383361 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/buttons/ButtonStats.java @@ -0,0 +1,66 @@ +package mineplex.clanshub.profile.buttons; + +import mineplex.clanshub.profile.gui.GUIProfile; +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +/** + * Button to open stats menu + */ +public class ButtonStats implements GuiItem +{ + private GUIProfile _profile; + private Player _player; + + public ButtonStats(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getAchievementManager().openShop(_player); + } + + @Override + public ItemStack getObject() + { + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, + ChatColor.RESET + C.cYellow + "Stats and Achievements", + new String[] + { + "", + C.cWhite + "View your Statistics and Achievements", + C.cWhite + "for all of the games on Mineplex!", + + "", + C.cWhite + "Type " + C.cGreen + "/stats" + C.cWhite + " to access this anywhere!" + }); + SkullMeta meta = ((SkullMeta) item.getItemMeta()); + meta.setOwner(_player.getName()); + item.setItemMeta(meta); + return item; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/gui/GUIProfile.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/gui/GUIProfile.java new file mode 100644 index 00000000..e14ab7fc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/profile/gui/GUIProfile.java @@ -0,0 +1,39 @@ +package mineplex.clanshub.profile.gui; + +import mineplex.clanshub.profile.buttons.ButtonPrefs; +import mineplex.clanshub.profile.buttons.ButtonStats; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.gui.SimpleGui; +import mineplex.core.preferences.PreferencesManager; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + * Profile GUI + */ +public class GUIProfile extends SimpleGui +{ + private PreferencesManager _preferencesManager; + private AchievementManager _achievementManager; + + public GUIProfile(Plugin plugin, Player player, PreferencesManager preferencesManager, AchievementManager achievementManager) + { + super(plugin, player, "My Profile", 9*3); + _preferencesManager = preferencesManager; + _achievementManager = achievementManager; + + setItem(12, new ButtonStats(this, player)); + setItem(14, new ButtonPrefs(this, player)); + } + + public PreferencesManager getPrefManager() + { + return _preferencesManager; + } + + public AchievementManager getAchievementManager() + { + return _achievementManager; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/HubQueueManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/HubQueueManager.java new file mode 100644 index 00000000..2eafbdb7 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/HubQueueManager.java @@ -0,0 +1,361 @@ +package mineplex.clanshub.queue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.mineplex.clansqueue.common.ClansQueueMessenger; +import com.mineplex.clansqueue.common.QueueConstant; +import com.mineplex.clansqueue.common.messages.PlayerJoinQueueCallbackMessage; +import com.mineplex.clansqueue.common.messages.PlayerJoinQueueMessage; +import com.mineplex.clansqueue.common.messages.PlayerLeaveQueueMessage; +import com.mineplex.clansqueue.common.messages.PlayerSendToServerMessage; +import com.mineplex.clansqueue.common.messages.QueueDeleteMessage; +import com.mineplex.clansqueue.common.messages.QueuePauseBroadcastMessage; +import com.mineplex.clansqueue.common.messages.QueuePauseUpdateMessage; +import com.mineplex.clansqueue.common.messages.QueueStatusMessage; + +import mineplex.clanshub.ClansTransferManager; +import mineplex.clanshub.ServerInfo; +import mineplex.clanshub.queue.data.ClansQueueData; +import mineplex.clanshub.queue.data.QueuePlayerData; +import mineplex.core.Managers; +import mineplex.core.MiniClientPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +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.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.core.portal.events.ServerTransferEvent; +import mineplex.core.punish.clans.ClansBanManager; +import mineplex.core.recharge.Recharge; + +@ReflectivelyCreateMiniPlugin +public class HubQueueManager extends MiniClientPlugin +{ + public enum Perm implements Permission + { + JOIN_PAUSED_QUEUE, + TOGGLE_QUEUE_PAUSE, + LIST_QUEUES, + } + + public enum QueuePriority implements Permission + { + BYPASS(QueueConstant.BYPASS_QUEUE_WEIGHT, PermissionGroup.CONTENT, PermissionGroup.TRAINEE), + PRIORITY(7, PermissionGroup.BUILDER), + ETERNAL(6, PermissionGroup.ETERNAL), + TITAN(5, PermissionGroup.TITAN), + LEGEND(4, PermissionGroup.LEGEND), + HERO(3, PermissionGroup.HERO), + ULTRA(2, PermissionGroup.ULTRA), + DEFAULT(1, PermissionGroup.PLAYER) + ; + + private final int _weight; + private final List _granted; + + private QueuePriority(int weight, PermissionGroup... granted) + { + _weight = weight; + _granted = Collections.unmodifiableList(Arrays.asList(granted)); + } + + public int getWeight() + { + return _weight; + } + + public List getGranted() + { + return _granted; + } + } + + private final CoreClientManager _clientManager = require(CoreClientManager.class); + private final ClansBanManager _punish = require(ClansBanManager.class); + private final Portal _portal = require(Portal.class); + private final Comparator _prioritySorter = (q1, q2) -> + { + if (q1.getWeight() == -1 && q2.getWeight() != -1) + { + return -1; + } + if (q2.getWeight() == -1 && q1.getWeight() != -1) + { + return 1; + } + + return Integer.compare(q2.getWeight(), q1.getWeight()); + }; + private final Map _queueData = new HashMap<>(); + private final ClansQueueMessenger _messenger; + + private HubQueueManager() + { + super("Queue Manager"); + + generatePermissions(); + _messenger = ClansQueueMessenger.getMessenger(UtilServer.getServerName()); + + _messenger.registerListener(PlayerJoinQueueCallbackMessage.class, (callback, origin) -> + { + runSync(() -> + { + Player player = Bukkit.getPlayer(callback.PlayerUUID); + if (player != null) + { + QueuePlayerData data = Get(player); + data.Queued = true; + data.QueuePosition = callback.Position; + UtilPlayer.message(player, F.main(getName(), "You have joined the queue for server " + F.elem(data.TargetServer) + "! Your position: " + F.greenElem("#" + data.QueuePosition))); + } + }); + }); + _messenger.registerListener(PlayerSendToServerMessage.class, (callback, origin) -> + { + runSync(() -> + { + Player player = Bukkit.getPlayer(callback.PlayerUUID); + if (player != null) + { + Get(player).Queued = false; + player.leaveVehicle(); + player.eject(); + _portal.sendPlayerToServer(player, callback.TargetServer, Intent.FORCE_TRANSFER); + } + }); + }); + _messenger.registerListener(QueueStatusMessage.class, (status, origin) -> + { + runSync(() -> + { + status.Snapshots.forEach(snapshot -> + { + ClansQueueData data = _queueData.computeIfAbsent(snapshot.ServerName, (name) -> new ClansQueueData(name)); + + data.QueueMembers = snapshot.Queue.size(); + data.QueuePaused = snapshot.Paused; + snapshot.Queue.entrySet().forEach(entry -> + { + Player player = Bukkit.getPlayer(entry.getKey()); + if (player != null) + { + Get(player).QueuePosition = entry.getValue(); + if (Recharge.Instance.use(player, "Queue Status Update", 7000, false, false)) + { + UtilPlayer.message(player, F.main(getName(), "Your position: " + F.greenElem("#" + entry.getValue()))); + } + } + }); + }); + }); + }); + _messenger.registerListener(QueuePauseBroadcastMessage.class, (broadcast, origin) -> + { + runSync(() -> + { + ClansQueueData data = _queueData.computeIfAbsent(broadcast.ServerName, (name) -> new ClansQueueData(name)); + data.QueuePaused = broadcast.Paused; + GetValues().forEach(qp -> + { + if (qp.TargetServer != null && qp.TargetServer.equals(broadcast.ServerName)) + { + UtilPlayer.message(Bukkit.getPlayer(qp.UniqueId), F.main(getName(), "Queue pause status: " + F.elem(broadcast.Paused))); + } + }); + }); + }); + _messenger.registerListener(QueueDeleteMessage.class, (delete, origin) -> + { + runSync(() -> + { + GetValues().forEach(qp -> + { + if (qp.TargetServer != null && qp.TargetServer.equals(delete.ServerName)) + { + UtilPlayer.message(Bukkit.getPlayer(qp.UniqueId), F.main(getName(), "Queue deleted.")); + } + qp.Queued = false; + qp.QueuePosition = 0; + qp.TargetServer = null; + }); + _queueData.remove(delete.ServerName); + }); + }); + addCommand(new CommandBase(this, Perm.TOGGLE_QUEUE_PAUSE, "pausequeue") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /pausequeue ")); + return; + } + ServerInfo info = Managers.get(ClansTransferManager.class).getServer(args[0]); + if (info != null) + { + ClansQueueData data = getData(info); + if (data != null) + { + QueuePauseUpdateMessage message = new QueuePauseUpdateMessage(); + message.ServerName = data.ServerName; + message.Paused = !data.QueuePaused; + _messenger.transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + UtilPlayer.message(caller, F.main(getName(), "Toggling queue pause")); + return; + } + } + UtilPlayer.message(caller, F.main(getName(), "Queue not found")); + } + }); + addCommand(new CommandBase(this, Perm.LIST_QUEUES, "listqueues") + { + @Override + public void Execute(Player caller, String[] args) + { + StringBuilder queues = new StringBuilder("Queues: ["); + queues.append(_queueData.values().stream().map(data -> data.ServerName).collect(Collectors.joining(", "))); + queues.append(']'); + UtilPlayer.message(caller, F.main(getName(), queues.toString())); + } + }); + } + + private void generatePermissions() + { + for (QueuePriority priority : QueuePriority.values()) + { + priority.getGranted().forEach(group -> group.setPermission(priority, true, true)); + } + PermissionGroup.ADMIN.setPermission(Perm.JOIN_PAUSED_QUEUE, true, true); + PermissionGroup.ADMIN.setPermission(Perm.LIST_QUEUES, true, true); + PermissionGroup.ADMIN.setPermission(Perm.TOGGLE_QUEUE_PAUSE, true, true); + } + + public QueuePriority getHighestPriority(Player player) + { + Optional opt = Stream.of(QueuePriority.values()).filter(_clientManager.Get(player)::hasPermission).sorted(_prioritySorter).findFirst(); + + if (opt.isPresent()) + { + return opt.get(); + } + + return QueuePriority.DEFAULT; + } + + public ClansQueueData getData(ServerInfo info) + { + return _queueData.get(info.Name); + } + + public void attemptEnterQueue(Player player, ClansQueueData data) + { + if (Get(player).TargetServer != null) + { + if (Get(player).Queued) + { + UtilPlayer.message(player, F.main(getName(), "You are already in a queue!")); + } + else + { + UtilPlayer.message(player, F.main(getName(), "You are already entering a queue!")); + } + return; + } + if (data.QueuePaused && !_clientManager.Get(player).hasPermission(Perm.JOIN_PAUSED_QUEUE)) + { + UtilPlayer.message(player, F.main(getName(), "That queue is paused and cannot currently be joined!")); + return; + } + Get(player).TargetServer = data.ServerName; + _punish.loadClient(player.getUniqueId(), client -> + { + if (client.isBanned()) + { + Get(player).TargetServer = null; + String time = UtilTime.convertString(client.getLongestBan().getTimeLeft(), 0, TimeUnit.FIT); + + if (client.getLongestBan().isPermanent()) + { + time = "Permanent"; + } + + String reason = C.cRedB + "You are banned from Clans for " + time + + "\n" + C.cWhite + client.getLongestBan().getReason(); + UtilPlayer.message(player, reason); + } + else + { + QueuePriority priority = getHighestPriority(player); + PlayerJoinQueueMessage message = new PlayerJoinQueueMessage(); + message.PlayerUUID = player.getUniqueId(); + message.TargetServer = data.ServerName; + message.PlayerPriority = priority.getWeight(); + _messenger.transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + UtilPlayer.message(player, F.main(getName(), "Joining queue...")); + } + }); + } + + public void leaveQueue(Player player, boolean informFailure) + { + if (!Get(player).Queued) + { + if (informFailure) + { + UtilPlayer.message(player, F.main(getName(), "You are not part of a queue!")); + } + return; + } + PlayerLeaveQueueMessage message = new PlayerLeaveQueueMessage(); + message.PlayerUUID = player.getUniqueId(); + message.TargetServer = Get(player).TargetServer; + _messenger.transmitMessage(message, QueueConstant.SERVICE_MESSENGER_IDENTIFIER); + Get(player).TargetServer = null; + Get(player).QueuePosition = 0; + Get(player).Queued = false; + UtilPlayer.message(player, F.main(getName(), "You have left the queue for " + F.elem(message.TargetServer) + "!")); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + leaveQueue(event.getPlayer(), false); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onTransfer(ServerTransferEvent event) + { + leaveQueue(event.getPlayer(), false); + } + + @Override + protected QueuePlayerData addPlayer(UUID uuid) + { + return new QueuePlayerData(uuid); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/data/ClansQueueData.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/data/ClansQueueData.java new file mode 100644 index 00000000..4512e409 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/data/ClansQueueData.java @@ -0,0 +1,30 @@ +package mineplex.clanshub.queue.data; + +public class ClansQueueData +{ + public final String ServerName; + public int QueueMembers; + public boolean QueuePaused; + + public ClansQueueData(String serverName) + { + ServerName = serverName; + } + + @Override + public int hashCode() + { + return ServerName.hashCode(); + } + + @Override + public boolean equals(Object o) + { + if (o == null || !getClass().isInstance(o)) + { + return false; + } + + return ((ClansQueueData)o).ServerName.equals(ServerName); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/data/QueuePlayerData.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/data/QueuePlayerData.java new file mode 100644 index 00000000..c0b05f97 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/queue/data/QueuePlayerData.java @@ -0,0 +1,36 @@ +package mineplex.clanshub.queue.data; + +import java.util.UUID; + +public class QueuePlayerData +{ + public final UUID UniqueId; + + public boolean Queued; + + public int QueuePosition; + + public String TargetServer; + + public QueuePlayerData(UUID uuid) + { + UniqueId = uuid; + } + + @Override + public boolean equals(Object o) + { + if (o == null || !getClass().isInstance(o)) + { + return false; + } + + return UniqueId.equals(((QueuePlayerData)o).UniqueId); + } + + @Override + public int hashCode() + { + return UniqueId.hashCode(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/RankSelectionButton.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/RankSelectionButton.java new file mode 100644 index 00000000..9e18ace1 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/RankSelectionButton.java @@ -0,0 +1,41 @@ +package mineplex.clanshub.salesannouncements; + +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; + +public class RankSelectionButton extends SalesAnnouncementGUIButton +{ + private SalesAnnouncementCreationPage _page; + private PermissionGroup _rank; + + public RankSelectionButton(PermissionGroup rank, SalesAnnouncementCreationPage page) + { + super(new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(rank.getDisplay(true, false, false, true)).addLore(C.cRed + "Click to Toggle On").build()); + _rank = rank; + _page = page; + } + + @Override + public void update() {} + + @Override + public void handleClick(ClickType type) + { + if (_page.Selected.contains(_rank)) + { + Button = new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(_rank.getDisplay(true, false, false, true)).addLore(C.cRed + "Click to Toggle On").build(); + _page.Selected.remove(_rank); + _page.updateButtons(true); + } + else + { + Button = new ItemBuilder(Material.EMERALD_BLOCK).setTitle(_rank.getDisplay(true, false, false, true)).addLore(C.cGreen + "Click to Toggle Off").build(); + _page.Selected.add(_rank); + _page.updateButtons(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/RankSelectionFinalizeButton.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/RankSelectionFinalizeButton.java new file mode 100644 index 00000000..ac60332f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/RankSelectionFinalizeButton.java @@ -0,0 +1,40 @@ +package mineplex.clanshub.salesannouncements; + +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; + +public class RankSelectionFinalizeButton extends SalesAnnouncementGUIButton +{ + private SalesAnnouncementCreationPage _page; + + public RankSelectionFinalizeButton(SalesAnnouncementCreationPage page) + { + super(new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(C.cRed + "Click to Finalize").addLore(C.cRed + "You must select at least one rank!").build()); + _page = page; + } + + @Override + public void update() + { + if (_page.Selected.isEmpty()) + { + Button = new ItemBuilder(Material.REDSTONE_BLOCK).setTitle(C.cRed + "Click to Finalize").addLore(C.cRed + "You must select at least one rank!").build(); + } + else + { + Button = new ItemBuilder(Material.EMERALD_BLOCK).setTitle(C.cGreen + "Click to Finalize").build(); + } + } + + @Override + public void handleClick(ClickType type) + { + if (!_page.Selected.isEmpty()) + { + _page.finalizeSelection(); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementButton.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementButton.java new file mode 100644 index 00000000..a901422f --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementButton.java @@ -0,0 +1,40 @@ +package mineplex.clanshub.salesannouncements; + +import org.bukkit.event.inventory.ClickType; + +public class SalesAnnouncementButton extends SalesAnnouncementGUIButton +{ + private SalesAnnouncementData _data; + private SalesAnnouncementPage _page; + + public SalesAnnouncementButton(SalesAnnouncementData data, SalesAnnouncementPage page) + { + super(data.getButtonForm()); + _data = data; + _page = page; + } + + public int getId() + { + return _data.getId(); + } + + @Override + public void update() + { + Button = _data.getButtonForm(); + } + + @Override + public void handleClick(ClickType type) + { + if (type == ClickType.RIGHT) + { + _page.deleteAnnouncement(_data); + } + else + { + _page.toggleAnnouncement(_data); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementCommand.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementCommand.java new file mode 100644 index 00000000..ed0bc91a --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementCommand.java @@ -0,0 +1,39 @@ +package mineplex.clanshub.salesannouncements; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; + +public class SalesAnnouncementCommand extends CommandBase +{ + public SalesAnnouncementCommand(SalesAnnouncementManager plugin) + { + super(plugin, SalesAnnouncementManager.Perm.SALES_COMMAND, "sales"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length > 1 && args[0].equalsIgnoreCase("add")) + { + StringBuilder message = new StringBuilder(); + message.append(args[1]); + for (int i = 2; i < args.length; i++) + { + message.append(" " + args[i]); + } + + new SalesAnnouncementCreationPage(caller, message.toString()); + } + else if (args.length >= 1) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage is /sales add (can take chat color codes)")); + } + else + { + new SalesAnnouncementPage(caller, Plugin); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementCreationPage.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementCreationPage.java new file mode 100644 index 00000000..4a369dfa --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementCreationPage.java @@ -0,0 +1,122 @@ +package mineplex.clanshub.salesannouncements; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; + +import mineplex.core.Managers; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class SalesAnnouncementCreationPage implements Listener +{ + private Player _viewer; + private Inventory _inv; + private String _message; + private Map _buttons = new HashMap<>(); + public List Selected = new ArrayList<>(); + + public SalesAnnouncementCreationPage(Player player, String message) + { + _viewer = player; + _message = message; + _inv = Bukkit.createInventory(player, 9 * 4, C.cGreen + "Select Ranks"); + setup(); + _viewer.openInventory(_inv); + UtilServer.RegisterEvents(this); + } + + private void setup() + { + int slot = 0; + for (PermissionGroup group : PermissionGroup.values()) + { + if (group.canBePrimary()) + { + _buttons.put(slot++, new RankSelectionButton(group, this)); + } + } + _buttons.put(31, new RankSelectionFinalizeButton(this)); + updateButtons(false); + } + + private void disable() + { + HandlerList.unregisterAll(this); + } + + public void finalizeSelection() + { + Managers.get(SalesAnnouncementManager.class).createAnnouncement(_viewer, Selected.toArray(new PermissionGroup[Selected.size()]), _message); + Managers.get(SalesAnnouncementManager.class).runSyncLater(() -> _viewer.closeInventory(), 1L); + } + + public void updateButtons(boolean callUpdate) + { + _inv.clear(); + _buttons.entrySet().stream().filter(entry -> entry.getKey() != 31).forEach(entry -> + { + if (callUpdate) + { + entry.getValue().update(); + } + _inv.setItem(entry.getKey(), entry.getValue().Button); + }); + if (callUpdate) + { + _buttons.get(31).update(); + } + _inv.setItem(31, _buttons.get(31).Button); + _viewer.updateInventory(); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (event.getType() == UpdateType.TICK) + { + if (_viewer.getOpenInventory() == null || _viewer.getOpenInventory().getTopInventory() == null || !_viewer.getOpenInventory().getTopInventory().getTitle().equals(_inv.getTitle())) + { + disable(); + return; + } + } + } + + @EventHandler + public void handleClick(InventoryClickEvent event) + { + if (event.getClickedInventory() == null || !event.getClickedInventory().getTitle().equals(_inv.getTitle())) + { + return; + } + if (!_viewer.getName().equals(event.getWhoClicked().getName())) + { + return; + } + event.setCancelled(true); + Integer slot = event.getSlot(); + if (!_buttons.containsKey(slot)) + { + return; + } + _buttons.get(slot).handleClick(event.getClick()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementData.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementData.java new file mode 100644 index 00000000..ea7cbf66 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementData.java @@ -0,0 +1,75 @@ +package mineplex.clanshub.salesannouncements; + +import java.util.Arrays; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; + +public class SalesAnnouncementData +{ + private final Integer _id; + private final PermissionGroup[] _displayTo; + private final String _message; + private boolean _enabled; + + public SalesAnnouncementData(Integer id, PermissionGroup[] displayTo, String message, boolean enabled) + { + _id = id; + _displayTo = displayTo; + _message = message; + _enabled = enabled; + } + + public Integer getId() + { + return _id; + } + + public PermissionGroup[] getDisplayTo() + { + return _displayTo; + } + + public boolean shouldDisplayTo(PermissionGroup rank) + { + return Arrays.asList(_displayTo).contains(rank); + } + + public String getMessage(boolean raw) + { + return raw ? _message : ChatColor.translateAlternateColorCodes('&', _message); + } + + public ItemStack getButtonForm() + { + Material type = Material.REDSTONE_BLOCK; + String lore = C.cRed + "Click to Enable, Right-Click to Delete"; + String excerpt = getMessage(false); + if (excerpt.length() > 9) + { + excerpt = excerpt.substring(0, 9) + C.Reset + "..."; + } + if (_enabled) + { + type = Material.EMERALD_BLOCK; + lore = C.cGreen + "Click to Disable, Right-Click to Delete"; + } + + return new ItemBuilder(type).setTitle("ID: " + getId()).setLore(excerpt, C.cRed + " ", lore).build(); + } + + public boolean isEnabled() + { + return _enabled; + } + + public void setEnabled(boolean enabled) + { + _enabled = enabled; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementDeleteCommand.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementDeleteCommand.java new file mode 100644 index 00000000..115d5985 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementDeleteCommand.java @@ -0,0 +1,32 @@ +package mineplex.clanshub.salesannouncements; + +import mineplex.serverdata.commands.ServerCommand; + +public class SalesAnnouncementDeleteCommand extends ServerCommand +{ + private Integer _id; + private String _from; + private boolean _clans; + + public SalesAnnouncementDeleteCommand(Integer id, String from, boolean clans) + { + _id = id; + _from = from; + _clans = clans; + } + + public Integer getId() + { + return _id; + } + + public String getFrom() + { + return _from; + } + + public boolean isClans() + { + return _clans; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementDeleteHandler.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementDeleteHandler.java new file mode 100644 index 00000000..b8ab47fd --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementDeleteHandler.java @@ -0,0 +1,27 @@ +package mineplex.clanshub.salesannouncements; + +import mineplex.serverdata.commands.CommandCallback; + +public class SalesAnnouncementDeleteHandler implements CommandCallback +{ + private final SalesAnnouncementManager _manager; + + public SalesAnnouncementDeleteHandler(SalesAnnouncementManager manager) + { + _manager = manager; + } + + @Override + public void run(SalesAnnouncementDeleteCommand command) + { + if (_manager.getServer().equalsIgnoreCase(command.getFrom())) + { + return; + } + if (_manager.CLANS != command.isClans()) + { + return; + } + _manager.handleRemoteDeletion(command.getId()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementGUIButton.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementGUIButton.java new file mode 100644 index 00000000..9c98fca4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementGUIButton.java @@ -0,0 +1,18 @@ +package mineplex.clanshub.salesannouncements; + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +public abstract class SalesAnnouncementGUIButton +{ + public ItemStack Button = null; + + public SalesAnnouncementGUIButton(ItemStack button) + { + Button = button; + } + + public abstract void update(); + + public abstract void handleClick(ClickType type); +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementManager.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementManager.java new file mode 100644 index 00000000..d0b01ec5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementManager.java @@ -0,0 +1,161 @@ +package mineplex.clanshub.salesannouncements; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.serverdata.commands.ServerCommandManager; + +public class SalesAnnouncementManager extends MiniPlugin +{ + public enum Perm implements Permission + { + SALES_COMMAND, + } + + private static final String LINE = C.cDGreenB + C.Strike + "============================================="; + private final Map _data = new HashMap<>(); + private final SalesAnnouncementRepository _repo; + public final boolean CLANS = true; + + public SalesAnnouncementManager(JavaPlugin plugin) + { + super("Sales", plugin); + _repo = new SalesAnnouncementRepository(plugin, CLANS); + _repo.loadAnnouncements(_data); + + addCommand(new SalesAnnouncementCommand(this)); + + ServerCommandManager.getInstance().registerCommandType(SalesAnnouncementUpdateCommand.class, new SalesAnnouncementUpdateHandler(this)); + ServerCommandManager.getInstance().registerCommandType(SalesAnnouncementDeleteCommand.class, new SalesAnnouncementDeleteHandler(this)); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.SALES_COMMAND, true, true); + } + + public Map getLoadedAnnouncements() + { + return _data; + } + + public String getServer() + { + return getPlugin().getConfig().getString("serverstatus.name"); + } + + public void createAnnouncement(Player creator, PermissionGroup[] displayTo, String message) + { + if (_data.size() >= 9 * 6) + { + UtilPlayer.message(creator, F.main(getName(), "There are too many existing Sales Announcements to create a new one! Try deleting some!")); + return; + } + _repo.createAnnouncement(displayTo, message, data -> + { + UtilPlayer.message(creator, F.main(getName(), "Announcement successfully created!")); + _data.put(data.getId(), data); + new SalesAnnouncementUpdateCommand(data.getId(), getServer(), CLANS).publish(); + }); + } + + public void deleteAnnouncement(Player deletor, SalesAnnouncementData data, boolean forceRemoveFromList) + { + if (forceRemoveFromList) + { + _data.remove(data.getId()); + } + _repo.deleteAnnouncement(data, () -> + { + UtilPlayer.message(deletor, F.main(getName(), "Successfully deleted announcement!")); + if (!forceRemoveFromList) + { + _data.remove(data.getId()); + } + new SalesAnnouncementDeleteCommand(data.getId(), getServer(), CLANS).publish(); + }); + } + + public void toggleAnnouncement(Player toggler, SalesAnnouncementData data) + { + data.setEnabled(!data.isEnabled()); + _repo.updateAnnouncementStatus(data, () -> + { + UtilPlayer.message(toggler, F.main(getName(), "Successfully toggled announcement!")); + new SalesAnnouncementUpdateCommand(data.getId(), getServer(), CLANS).publish(); + }); + } + + public void handleRemoteDeletion(int id) + { + runSync(() -> + { + _data.remove(id); + UtilServer.CallEvent(new SalesAnnouncementRemoteListUpdateEvent()); + }); + } + + public void handleRemoteUpdate(int id) + { + runSync(() -> + { + if (_data.containsKey(id)) + { + _repo.loadAnnouncement(id, data -> + { + _data.get(data.getId()).setEnabled(data.isEnabled()); + UtilServer.CallEvent(new SalesAnnouncementRemoteListUpdateEvent()); + }); + } + else + { + _repo.loadAnnouncement(id, data -> + { + _data.put(data.getId(), data); + UtilServer.CallEvent(new SalesAnnouncementRemoteListUpdateEvent()); + }); + } + }); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + if (_data.isEmpty() || !_data.values().stream().filter(data -> data.isEnabled()).findAny().isPresent()) + { + return; + } + Player player = event.getPlayer(); + PermissionGroup rank = Managers.get(CoreClientManager.class).Get(player).getPrimaryGroup(); + + runSyncLater(() -> + { + _data.values().stream().filter(data -> data.isEnabled() && data.shouldDisplayTo(rank)).forEach(data -> + { + player.sendMessage(" "); + player.sendMessage(LINE); + player.sendMessage(" "); + player.sendMessage(data.getMessage(false)); + player.sendMessage(" "); + player.sendMessage(LINE); + player.sendMessage(" "); + }); + }, 5L); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementPage.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementPage.java new file mode 100644 index 00000000..96640966 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementPage.java @@ -0,0 +1,122 @@ +package mineplex.clanshub.salesannouncements; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class SalesAnnouncementPage implements Listener +{ + private Player _viewer; + private Inventory _inv; + private SalesAnnouncementManager _manager; + private Map _buttons = new HashMap<>(); + + public SalesAnnouncementPage(Player player, SalesAnnouncementManager manager) + { + _viewer = player; + _manager = manager; + _inv = Bukkit.createInventory(player, 9 * 6, C.cGreen + "All Sales Announcements"); + setup(); + _viewer.openInventory(_inv); + UtilServer.RegisterEvents(this); + } + + private void setup() + { + _buttons.clear(); + int i = 0; + for (SalesAnnouncementData data : _manager.getLoadedAnnouncements().values()) + { + _buttons.put(i, new SalesAnnouncementButton(data, this)); + i++; + } + updateButtons(false); + } + + private void disable() + { + HandlerList.unregisterAll(this); + } + + public void deleteAnnouncement(SalesAnnouncementData data) + { + _manager.deleteAnnouncement(_viewer, data, true); + _manager.runSyncLater(() -> setup(), 2L); + } + + public void toggleAnnouncement(SalesAnnouncementData data) + { + _manager.toggleAnnouncement(_viewer, data); + updateButtons(true); + } + + public void updateButtons(boolean callUpdate) + { + _inv.clear(); + _buttons.entrySet().stream().forEach(entry -> + { + if (callUpdate) + { + entry.getValue().update(); + } + _inv.setItem(entry.getKey(), entry.getValue().Button); + }); + _viewer.updateInventory(); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (event.getType() == UpdateType.TICK) + { + if (_viewer.getOpenInventory() == null || _viewer.getOpenInventory().getTopInventory() == null || !_viewer.getOpenInventory().getTopInventory().getTitle().equals(_inv.getTitle())) + { + disable(); + return; + } + } + } + + @EventHandler + public void handleClick(InventoryClickEvent event) + { + if (event.getClickedInventory() == null || !event.getClickedInventory().getTitle().equals(_inv.getTitle())) + { + return; + } + if (!_viewer.getName().equals(event.getWhoClicked().getName())) + { + return; + } + event.setCancelled(true); + Integer slot = event.getSlot(); + if (!_buttons.containsKey(slot)) + { + return; + } + _buttons.get(slot).handleClick(event.getClick()); + } + + @EventHandler + public void onListChange(SalesAnnouncementRemoteListUpdateEvent event) + { + setup(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementRemoteListUpdateEvent.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementRemoteListUpdateEvent.java new file mode 100644 index 00000000..d8578fa0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementRemoteListUpdateEvent.java @@ -0,0 +1,21 @@ +package mineplex.clanshub.salesannouncements; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class SalesAnnouncementRemoteListUpdateEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + + public SalesAnnouncementRemoteListUpdateEvent() {} + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementRepository.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementRepository.java new file mode 100644 index 00000000..a2637ba4 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementRepository.java @@ -0,0 +1,181 @@ +package mineplex.clanshub.salesannouncements; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.account.permissions.PermissionGroupHelper; +import mineplex.core.common.util.Callback; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnBoolean; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class SalesAnnouncementRepository extends RepositoryBase +{ + private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS salesAnnouncements (id INT NOT NULL AUTO_INCREMENT, ranks VARCHAR(250), message VARCHAR(256), enabled BOOL, clans BOOL, PRIMARY KEY (id), INDEX typeIndex (clans));"; + + private static final String GET_ANNOUNCEMENTS = "SELECT * FROM salesAnnouncements WHERE clans=?;"; + private static final String GET_ANNOUNCEMENT = "SELECT * FROM salesAnnouncements WHERE id=?;"; + private static final String UPDATE_ANNOUNCEMENT_STATUS = "UPDATE salesAnnouncements SET enabled=? WHERE id=?;"; + private static final String INSERT_ANNOUNCEMENT = "INSERT INTO salesAnnouncements (ranks, message, enabled, clans) VALUES(?, ?, ?, ?);"; + private static final String DELETE_ANNOUNCEMENT = "DELETE FROM salesAnnouncements WHERE id=?;"; + + private final JavaPlugin _plugin; + private final boolean _clans; + + public SalesAnnouncementRepository(JavaPlugin plugin, boolean clans) + { + super(DBPool.getAccount()); + _plugin = plugin; + _clans = clans; + } + + private void runAsync(Runnable runnable) + { + Bukkit.getScheduler().runTaskAsynchronously(_plugin, runnable); + } + + private void runSync(Runnable runnable) + { + Bukkit.getScheduler().runTask(_plugin, runnable); + } + + public void loadAnnouncements(final Map map) + { + runAsync(() -> + { + executeQuery(GET_ANNOUNCEMENTS, resultSet -> + { + final List data = new ArrayList<>(); + while (resultSet.next()) + { + int id = resultSet.getInt("id"); + String rankString = resultSet.getString("ranks"); + List ranks = new ArrayList<>(); + if (rankString.contains(",") && !rankString.startsWith(",") && !rankString.endsWith(",")) + { + for (String rankStr : rankString.split(",")) + { + PermissionGroup group = PermissionGroupHelper.getGroupFromLegacy(rankStr); + ranks.add(group); + } + } + else + { + PermissionGroup group = PermissionGroupHelper.getGroupFromLegacy(rankString); + ranks.add(group); + } + PermissionGroup[] displayTo = ranks.toArray(new PermissionGroup[ranks.size()]); + String message = resultSet.getString("message"); + boolean enabled = resultSet.getBoolean("enabled"); + + data.add(new SalesAnnouncementData(id, displayTo, message, enabled)); + } + + runSync(() -> + { + map.clear(); + data.forEach(sData -> map.put(sData.getId(), sData)); + }); + }, new ColumnBoolean("clans", _clans)); + }); + } + + public void loadAnnouncement(final int id, final Callback callback) + { + runAsync(() -> + { + executeQuery(GET_ANNOUNCEMENT, resultSet -> + { + if (resultSet.next()) + { + int aId = resultSet.getInt("id"); + String rankString = resultSet.getString("ranks"); + List ranks = new ArrayList<>(); + if (rankString.contains(",") && !rankString.startsWith(",") && !rankString.endsWith(",")) + { + for (String rankStr : rankString.split(",")) + { + PermissionGroup group = PermissionGroupHelper.getGroupFromLegacy(rankStr); + ranks.add(group); + } + } + else + { + PermissionGroup group = PermissionGroupHelper.getGroupFromLegacy(rankString); + ranks.add(group); + } + PermissionGroup[] displayTo = ranks.toArray(new PermissionGroup[ranks.size()]); + String message = resultSet.getString("message"); + boolean enabled = resultSet.getBoolean("enabled"); + + final SalesAnnouncementData data = new SalesAnnouncementData(aId, displayTo, message, enabled); + runSync(() -> + { + callback.run(data); + }); + } + }, new ColumnInt("id", id)); + }); + } + + public void createAnnouncement(final PermissionGroup[] displayTo, final String message, Callback callback) + { + runAsync(() -> + { + StringBuilder rankStr = new StringBuilder(displayTo[0].name()); + for (int i = 1; i < displayTo.length; i++) + { + rankStr.append(",").append(displayTo[i].name()); + } + executeInsert(INSERT_ANNOUNCEMENT, resultSet -> + { + if (resultSet.next()) + { + int id = resultSet.getInt(1); + final SalesAnnouncementData data = new SalesAnnouncementData(id, displayTo, message, true); + if (callback != null) + { + runSync(() -> callback.run(data)); + } + } + }, new ColumnVarChar("ranks", 250, rankStr.toString()), new ColumnVarChar("message", 256, message), new ColumnBoolean("enabled", true), new ColumnBoolean("clans", _clans)); + }); + } + + public void updateAnnouncementStatus(SalesAnnouncementData data, Runnable after) + { + runAsync(() -> + { + executeUpdate(UPDATE_ANNOUNCEMENT_STATUS, new ColumnBoolean("enabled", data.isEnabled()), new ColumnInt("id", data.getId())); + if (after != null) + { + runSync(after); + } + }); + } + + public void deleteAnnouncement(SalesAnnouncementData data, Runnable after) + { + runAsync(() -> + { + executeUpdate(DELETE_ANNOUNCEMENT, new ColumnInt("id", data.getId())); + if (after != null) + { + runSync(after); + } + }); + } + + @Override + protected void initialize() {} + + @Override + protected void update() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementUpdateCommand.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementUpdateCommand.java new file mode 100644 index 00000000..16edeabc --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementUpdateCommand.java @@ -0,0 +1,32 @@ +package mineplex.clanshub.salesannouncements; + +import mineplex.serverdata.commands.ServerCommand; + +public class SalesAnnouncementUpdateCommand extends ServerCommand +{ + private Integer _id; + private String _from; + private boolean _clans; + + public SalesAnnouncementUpdateCommand(Integer id, String from, boolean clans) + { + _id = id; + _from = from; + _clans = clans; + } + + public Integer getId() + { + return _id; + } + + public String getFrom() + { + return _from; + } + + public boolean isClans() + { + return _clans; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementUpdateHandler.java b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementUpdateHandler.java new file mode 100644 index 00000000..d2771b95 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub.Clans/src/mineplex/clanshub/salesannouncements/SalesAnnouncementUpdateHandler.java @@ -0,0 +1,27 @@ +package mineplex.clanshub.salesannouncements; + +import mineplex.serverdata.commands.CommandCallback; + +public class SalesAnnouncementUpdateHandler implements CommandCallback +{ + private final SalesAnnouncementManager _manager; + + public SalesAnnouncementUpdateHandler(SalesAnnouncementManager manager) + { + _manager = manager; + } + + @Override + public void run(SalesAnnouncementUpdateCommand command) + { + if (_manager.getServer().equalsIgnoreCase(command.getFrom())) + { + return; + } + if (_manager.CLANS != command.isClans()) + { + return; + } + _manager.handleRemoteUpdate(command.getId()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Hub/dependency-reduced-pom.xml b/Plugins[Modified]/Mineplex.Hub/dependency-reduced-pom.xml deleted file mode 100644 index a83628f4..00000000 --- a/Plugins[Modified]/Mineplex.Hub/dependency-reduced-pom.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - mineplex-plugin - com.mineplex - dev-SNAPSHOT - ../plugin.xml - - 4.0.0 - mineplex-hub - Hub - - diff --git a/Plugins[Modified]/Mineplex.Hub/pom.xml b/Plugins[Modified]/Mineplex.Hub/pom.xml index 6d0b0566..6e2950ee 100644 --- a/Plugins[Modified]/Mineplex.Hub/pom.xml +++ b/Plugins[Modified]/Mineplex.Hub/pom.xml @@ -14,6 +14,13 @@ mineplex-hub + ${project.groupId} mineplex-minecraft-game-classcombat diff --git a/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/Hub.java index af136070..e0cf6e84 100644 --- a/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -6,9 +6,11 @@ import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.CustomTagFix; import mineplex.core.PacketsInteractionFix; +//import mineplex.core.TwitchIntegrationFix; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; import mineplex.core.admin.command.AdminCommands; +//import mineplex.core.antihack.AntiHack; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.boosters.BoosterManager; import mineplex.core.chat.Chat; @@ -132,7 +134,7 @@ public class Hub extends JavaPlugin implements IRelation Portal portal = new Portal(); - + //require(AntiHack.class); IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal); @@ -201,6 +203,7 @@ public class Hub extends JavaPlugin implements IRelation require(TwoFactorAuth.class); require(TeamspeakManager.class); require(WebsiteLinkManager.class); + //require(TwitchIntegrationFix.class); require(SoundNotifier.class); new AdminCommands(); diff --git a/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/HubManager.java index 3a5344ab..bab05488 100644 --- a/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins[Modified]/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -1,5 +1,34 @@ package mineplex.hub; +import java.util.List; +import java.util.UUID; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.TextComponent; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.WorldServer; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerVelocityEvent; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.scheduler.BukkitRunnable; + import mineplex.core.Managers; import mineplex.core.MiniClientPlugin; import mineplex.core.account.CoreClient; @@ -16,7 +45,12 @@ import mineplex.core.chat.Chat; import mineplex.core.chat.format.LevelFormatComponent; import mineplex.core.chat.format.RankFormatComponent; import mineplex.core.common.generator.VoidGenerator; -import mineplex.core.common.util.*; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.communities.CommunityManager; import mineplex.core.cosmetic.CosmeticManager; import mineplex.core.disguise.DisguiseManager; @@ -74,25 +108,6 @@ import mineplex.hub.scoreboard.HubScoreboard; import mineplex.hub.world.HubWorldManager; import mineplex.minecraft.game.core.combat.DeathMessageType; import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.TextComponent; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.minecraft.server.v1_8_R3.WorldServer; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityTargetEvent.TargetReason; -import org.bukkit.event.player.*; -import org.bukkit.event.server.ServerListPingEvent; - -import java.util.List; -import java.util.UUID; public class HubManager extends MiniClientPlugin { @@ -167,7 +182,7 @@ public class HubManager extends MiniClientPlugin new BonusManager(_plugin, null, clientManager, donationManager, pollManager, npcManager, hologramManager, statsManager, inventoryManager, petManager, youtubeManager, _gadgetManager, thankManager, "Carl"); TreasureManager treasureManager = require(TreasureManager.class); - new CosmeticManager(_plugin, clientManager, donationManager, inventoryManager, _gadgetManager, petManager, treasureManager, null, punish); + new CosmeticManager(_plugin, clientManager, donationManager, inventoryManager, _gadgetManager, petManager, treasureManager, boosterManager, punish); for (Location location : _worldData.getSpongeLocations("TREASURE CHEST")) { @@ -244,6 +259,43 @@ public class HubManager extends MiniClientPlugin // Disable chunk generation nmsWorld.generator = new VoidGenerator(); + // Disable saving, enable chunk unloading + //nmsWorld.spigotConfig.saveWorld = false; + //TODO: prob some custom config? idk we can do this + + //nmsWorld.spigotConfig.unloadChunks = true; + + // Unload chunks every 60 seconds + new BukkitRunnable() + { + @Override + public void run() + { + int count = 0; + for (World world : _plugin.getServer().getWorlds()) + { + WorldServer nmsWorld = ((CraftWorld) world).getHandle(); + //Always true according to above + /* + if (nmsWorld.spigotConfig.unloadChunks != Boolean.TRUE) + continue; + */ + //boolean save = !nmsWorld.isSavingDisabled(); + boolean save = !nmsWorld.savingDisabled; + for (Chunk chunk : world.getLoadedChunks()) + { + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk); + _plugin.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled() && chunk.unload(save, true)) + count++; + } + } + + if (count > 9) + System.out.println("Unloaded " + count + " chunks."); + } + }.runTaskTimer(_plugin, 20L, 20L * 60L); + generatePermissions(); } diff --git a/Plugins[Modified]/Mineplex.Hub/target/classes/plugin.yml b/Plugins[Modified]/Mineplex.Hub/target/classes/plugin.yml new file mode 100644 index 00000000..c17c65c0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub/target/classes/plugin.yml @@ -0,0 +1,4 @@ +name: Hub +main: mineplex.hub.Hub +version: 0.1 +loadbefore: [MineplexAnticheat] diff --git a/Plugins[Modified]/Mineplex.Hub/target/maven-archiver/pom.properties b/Plugins[Modified]/Mineplex.Hub/target/maven-archiver/pom.properties new file mode 100644 index 00000000..a090f993 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub/target/maven-archiver/pom.properties @@ -0,0 +1,4 @@ +#Created by Apache Maven 3.8.1 +groupId=com.mineplex +artifactId=mineplex-hub +version=dev-SNAPSHOT diff --git a/Plugins[Modified]/Mineplex.Hub/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Plugins[Modified]/Mineplex.Hub/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 00000000..e69de29b diff --git a/Plugins[Modified]/Mineplex.Hub/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Plugins[Modified]/Mineplex.Hub/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 00000000..2493c7e2 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Hub/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,114 @@ +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\HubManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\MissionsComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\SingleWinnerComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\duel\Duels.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\basketball\ThrowData.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\ServerSelectionShop.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\HubVisibilityManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\damage\PVPTrackerComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\MPSServerSelectionPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\ServerSelectionPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\GameServer.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\ForcefieldManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\CakeWarsServerSelectionPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\commands\ForcefieldRadius.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\NewsRepository.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\gimmicks\staffbuild\BuildHistoryCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\command\NewsCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementRemoteListUpdateEvent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\scoreboard\HubScoreboardLine.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementCreationPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementUpdateHandler.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\GameDescriptionComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\HubGameType.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\player\HubPlayerManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\treasurehunt\TreasureHuntManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\map\PreventNonAlivePlayersComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\GameTimeoutComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\HubGame.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\NewsManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\basketball\BasketballManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\damage\DamageComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\EasterEggHunt.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\commands\GadgetToggle.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\gimmicks\staffbuild\ClearBuildCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\gimmicks\AdminPunch.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\event\HubGameStateChangeEvent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ServerManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementDeleteHandler.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\ui\HubGamesPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\command\NewsDeleteCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\player\CreativeManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\command\NetGroupCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\kit\HubKitManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\game\QuickShop.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\MavericksManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\event\HubGamePlayerDeathEvent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\basketball\BasketballGame.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementButton.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\map\BlockRecorderComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\ServerModeSelectionPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\plugin\ChristmasHubPlugin.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\commands\EggAddCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\lobby\LobbyShop.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\NewsElement.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\doublejump\DoubleJumpPrepareEvent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\command\NewsRefreshCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\plugin\HalloweenHubPlugin.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\gimmicks\SecretAreas.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\redis\NewsUpdateCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\parkour\data\SprintingParkourData.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\DoubleJumpComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\HubClient.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\plugin\AnniversaryHubPlugin.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\treasurehunt\TreasureHunt.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\command\NewsAddCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\PlayerGameModeComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\RankSelectionButton.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\lobby\LobbyMenu.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementRepository.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\tron\Tron.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\PlacesComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\world\HubWorldManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\HubGameManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\CycledGame.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\player\command\CreativeCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\parkour\data\SnakeParkourData.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\command\NewsListCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\doublejump\JumpManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\InventoryEditComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\SoccerManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\MavericksPortalManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\basketball\BasketballTeam.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementDeleteCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\ChampionsServerSelectionPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\HubGameComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\RankSelectionFinalizeButton.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\parkour\ParkourAttempt.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\treasurehunt\types\NewHubTreasureHunt.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\plugin\HubPlugin.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\command\NetStatCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\basketball\DataLoc.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\gimmicks\staffbuild\StaffBuild.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\general\PrepareFreezeComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\ui\HubGameShop.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\command\NetInfoCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\mavericks\MavericksWorldManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\parkour\ParkourData.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\news\SalesBoardManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementGUIButton.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\common\map\TeleportIntoMapComponent.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\tron\TronBike.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\parkour\ParkourManager.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\game\ServerGameMenu.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\hubgame\SimpleGame.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\treasurehunt\TreasureHuntRepository.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementUpdateCommand.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\Hub.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\modules\salesannouncements\SalesAnnouncementData.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\scoreboard\HubScoreboard.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\server\ui\server\ServerTeamsSelectionPage.java +E:\Mineplex\Mineplex\Mineplex.Hub\src\mineplex\hub\parkour\data\Snake.java diff --git a/Plugins[Modified]/Mineplex.MapParser/dependency-reduced-pom.xml b/Plugins[Modified]/Mineplex.MapParser/dependency-reduced-pom.xml deleted file mode 100644 index fd5f99d0..00000000 --- a/Plugins[Modified]/Mineplex.MapParser/dependency-reduced-pom.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - mineplex-plugin - com.mineplex - dev-SNAPSHOT - ../plugin.xml - - 4.0.0 - mineplex-mapparser - MapParser - - diff --git a/Plugins[Modified]/Mineplex.MapParser/pom.xml b/Plugins[Modified]/Mineplex.MapParser/pom.xml index 4e3eb5e8..1fd1baad 100644 --- a/Plugins[Modified]/Mineplex.MapParser/pom.xml +++ b/Plugins[Modified]/Mineplex.MapParser/pom.xml @@ -23,10 +23,5 @@ mineplex-core-common-base ${project.version} - - com.labalityowo - spigot - compile - diff --git a/Plugins[Modified]/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java b/Plugins[Modified]/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java index 1cb9875c..c13f0868 100644 --- a/Plugins[Modified]/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java +++ b/Plugins[Modified]/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java @@ -1,29 +1,78 @@ package mineplex.mapparser; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilBlockBase; -import mineplex.core.common.util.UtilPlayerBase; -import mineplex.mapparser.command.*; -import mineplex.mapparser.command.teleport.BackCommand; -import mineplex.mapparser.command.teleport.TeleportCommand; -import mineplex.mapparser.command.teleport.TeleportManager; -import mineplex.mapparser.command.teleport.TopCommand; -import mineplex.mapparser.module.Module; -import mineplex.mapparser.module.modules.*; -import org.bukkit.*; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.WorldCreator; import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -import java.io.File; -import java.io.IOException; -import java.util.*; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlockBase; +import mineplex.core.common.util.UtilPlayerBase; +import mineplex.mapparser.command.AddLoreCommand; +import mineplex.mapparser.command.AddSplashTextCommand; +import mineplex.mapparser.command.AdminCommand; +import mineplex.mapparser.command.AuthorCommand; +import mineplex.mapparser.command.ClearLoreCommand; +import mineplex.mapparser.command.CommandListCommand; +import mineplex.mapparser.command.CopyCommand; +import mineplex.mapparser.command.CopySchematicsCommand; +import mineplex.mapparser.command.CreateCommand; +import mineplex.mapparser.command.CurrentlyLiveCommand; +import mineplex.mapparser.command.DeleteCommand; +import mineplex.mapparser.command.FlySpeedCommand; +import mineplex.mapparser.command.GameTypeCommand; +import mineplex.mapparser.command.HubCommand; +import mineplex.mapparser.command.GameTypeInfoCommand; +import mineplex.mapparser.command.ItemNameCommand; +import mineplex.mapparser.command.ListCommand; +import mineplex.mapparser.command.LockCommand; +import mineplex.mapparser.command.MapCommand; +import mineplex.mapparser.command.MapInfoCommand; +import mineplex.mapparser.command.NameCommand; +import mineplex.mapparser.command.PMCommand; +import mineplex.mapparser.command.ParseCommand; +import mineplex.mapparser.command.ParseCommand200; +import mineplex.mapparser.command.ParseCommand400; +import mineplex.mapparser.command.ParseCommand600; +import mineplex.mapparser.command.ParseCommand1000; +import mineplex.mapparser.command.PlayerHeadCommand; +import mineplex.mapparser.command.RefreshWorldEditCommand; +import mineplex.mapparser.command.RenameCommand; +import mineplex.mapparser.command.SaveCommand; +import mineplex.mapparser.command.SetSpawnCommand; +import mineplex.mapparser.command.SpawnCommand; +import mineplex.mapparser.command.TimeCommand; +import mineplex.mapparser.command.WarpCommand; +import mineplex.mapparser.command.WorldsCommand; +import mineplex.mapparser.command.teleport.BackCommand; +import mineplex.mapparser.command.teleport.TeleportCommand; +import mineplex.mapparser.command.teleport.TeleportManager; +import mineplex.mapparser.command.teleport.TopCommand; +import mineplex.mapparser.module.Module; +import mineplex.mapparser.module.modules.CommandModule; +import mineplex.mapparser.module.modules.EventModule; +import mineplex.mapparser.module.modules.MMMazeModule; +import mineplex.mapparser.module.modules.SignModule; +import mineplex.mapparser.module.modules.TreeToolModule; public class MapParser extends JavaPlugin { @@ -41,7 +90,6 @@ public class MapParser extends JavaPlugin @Override public void onEnable() { - System.out.println(getDataFolder()); _worldManager = new WorldManager(this); getServer().getWorlds().get(0).setSpawnLocation(0, 106, 0); diff --git a/Plugins[Modified]/Mineplex.MapParser/target/classes/plugin.yml b/Plugins[Modified]/Mineplex.MapParser/target/classes/plugin.yml new file mode 100644 index 00000000..12fc5665 --- /dev/null +++ b/Plugins[Modified]/Mineplex.MapParser/target/classes/plugin.yml @@ -0,0 +1,3 @@ +name: MapParser +main: mineplex.mapparser.MapParser +version: 1 \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ServerData/pom.xml b/Plugins[Modified]/Mineplex.ServerData/pom.xml index 7c7f5152..299f2796 100644 --- a/Plugins[Modified]/Mineplex.ServerData/pom.xml +++ b/Plugins[Modified]/Mineplex.ServerData/pom.xml @@ -8,7 +8,7 @@ mineplex-parent dev-SNAPSHOT - + 23.0 @@ -17,8 +17,8 @@ - com.labalityowo - spigot + com.google.code.gson + gson mysql diff --git a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/Utility.java b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/Utility.java index 9f04cd93..dd8ba8f6 100644 --- a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/Utility.java +++ b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/Utility.java @@ -1,13 +1,16 @@ package mineplex.serverdata; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import com.google.gson.Gson; + import mineplex.serverdata.servers.ConnectionData; import mineplex.serverdata.servers.ServerManager; + import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; -import com.google.gson.Gson; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; /** * Utility offers various necessary utility-based methods for use in Mineplex.ServerData. @@ -102,28 +105,20 @@ public class Utility { synchronized(_poolLock) { - String key = "127.0.0.1:6379"; - if(connData != null){ - key = getConnKey(connData); - } + String key = getConnKey(connData); JedisPool pool = _pools.get(key); - + if (pool == null) { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); - jedisPoolConfig.setMaxWaitMillis(1000); jedisPoolConfig.setMinIdle(5); - jedisPoolConfig.setTestOnBorrow(true); +// jedisPoolConfig.setTestOnBorrow(true); jedisPoolConfig.setMaxTotal(20); jedisPoolConfig.setBlockWhenExhausted(true); - if(connData != null){ - pool = new JedisPool(jedisPoolConfig, connData.getHost(), connData.getPort()); - }else{ - pool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379); - } + pool = new JedisPool(jedisPoolConfig, connData.getHost(), connData.getPort()); _pools.put(key, pool); } diff --git a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DBPool.java b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DBPool.java index ce58ddf7..d948b6e7 100644 --- a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DBPool.java +++ b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DBPool.java @@ -1,9 +1,14 @@ package mineplex.serverdata.database; -import org.apache.commons.dbcp2.BasicDataSource; - import javax.sql.DataSource; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.file.Files; import java.sql.Connection; +import java.util.List; + +import org.apache.commons.dbcp2.BasicDataSource; public final class DBPool { @@ -92,16 +97,6 @@ public final class DBPool private static void loadDataSources() { - String dbHost = "127.0.0.1"; - String userName = "root"; - String password = "root"; - ACCOUNT = openDataSource("jdbc:mysql://" + dbHost + "/account", userName, password); - QUEUE = openDataSource("jdbc:mysql://" + dbHost + "/queue", userName, password); - MINEPLEX = openDataSource("jdbc:mysql://" + dbHost + "/mineplex", userName, password); - MINEPLEX_STATS = openDataSource("jdbc:mysql://" + dbHost + "/mineplex_stats", userName, password); - PLAYER_STATS = openDataSource("jdbc:mysql://" + dbHost + "/player_stats", userName, password); - SERVER_STATS = openDataSource("jdbc:mysql://" + dbHost + "/server_stats", userName, password); - /* try { File configFile = new File("database-config.dat"); @@ -125,32 +120,20 @@ public final class DBPool exception.printStackTrace(); System.out.println("---Unable To Parse DBPOOL Configuration File---"); } - - */ } private static void deserializeConnection(String line) { - /* String[] args = line.split(" "); if (args.length == 4) { - String dbHost = args[0]; - String userName = args[1]; - String password = args[2]; + String dbSource = args[0]; + String dbHost = args[1]; + String userName = args[2]; + String password = args[3]; - System.out.println(userName.toString()); - System.out.println(dbHost.toString()); - System.out.println(password.toString()); - - ACCOUNT = openDataSource("jdbc:mysql://" + dbHost, userName, password); - QUEUE = openDataSource("jdbc:mysql://" + dbHost, userName, password); - MINEPLEX = openDataSource("jdbc:mysql://" + dbHost, userName, password); - MINEPLEX_STATS = openDataSource("jdbc:mysql://" + dbHost, userName, password); - PLAYER_STATS = openDataSource("jdbc:mysql://" + dbHost, userName, password); - SERVER_STATS = openDataSource("jdbc:mysql://" + dbHost, userName, password); - MSSQL_MOCK = openDataSource("jdbc:mysql://" + dbHost, userName, password); + // System.out.println(dbSource + " " + dbHost + " " + userName + " " + password); if (dbSource.toUpperCase().equalsIgnoreCase("ACCOUNT")) ACCOUNT = openDataSource("jdbc:mysql://" + dbHost, userName, password); @@ -167,6 +150,5 @@ public final class DBPool else if (dbSource.toUpperCase().equalsIgnoreCase("MSSQL_MOCK")) MSSQL_MOCK = openDataSource("jdbc:mysql://" + dbHost, userName, password); } - */ } } diff --git a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DatabaseRunnable.java b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DatabaseRunnable.java index 6aa95c8f..70b9a996 100644 --- a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DatabaseRunnable.java +++ b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/database/DatabaseRunnable.java @@ -2,8 +2,6 @@ package mineplex.serverdata.database; import java.util.concurrent.atomic.AtomicInteger; -import org.omg.CORBA.ACTIVITY_REQUIRED; - public class DatabaseRunnable { private Runnable _runnable; diff --git a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java index e1df2f49..913db74e 100644 --- a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java +++ b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java @@ -10,7 +10,7 @@ import mineplex.serverdata.servers.ConnectionData.ConnectionType; public class RedisConfig { // Failsafe values in case configuration is not provided - private static final String DEFAULT_IP = "127.0.0.1"; + private static final String DEFAULT_IP = "10.3.203.80"; private static final int DEFAULT_PORT = 6379; private static Random random = new Random(); // Utility random @@ -38,6 +38,7 @@ public class RedisConfig /** * {@code writeable} defaults to {@literal true}. + * @see #getConnection(boolean) */ public ConnectionData getConnection() { diff --git a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java index 70746d30..2f553743 100644 --- a/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java +++ b/Plugins[Modified]/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisServerRepository.java @@ -1,5 +1,14 @@ package mineplex.serverdata.redis; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + import mineplex.serverdata.Region; import mineplex.serverdata.Utility; import mineplex.serverdata.data.DedicatedServer; @@ -7,10 +16,13 @@ import mineplex.serverdata.data.MinecraftServer; import mineplex.serverdata.data.ServerGroup; import mineplex.serverdata.servers.ConnectionData; import mineplex.serverdata.servers.ServerRepository; -import redis.clients.jedis.*; - -import java.util.*; -import java.util.Map.Entry; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.Pipeline; +import redis.clients.jedis.Response; +import redis.clients.jedis.Transaction; +import redis.clients.jedis.Tuple; +import redis.clients.jedis.exceptions.JedisConnectionException; /** * RedisServerRepository offers a Redis-based implementation of {@link ServerRepository} @@ -40,6 +52,7 @@ public class RedisServerRepository extends RedisRepository implements ServerRepo { String setKey = concatenate("serverstatus", "minecraft", getRegion().toString()); Pipeline pipeline = jedis.pipelined(); + List> responses = new ArrayList>(); for (String serverName : getActiveNames(setKey)) { @@ -63,6 +76,7 @@ public class RedisServerRepository extends RedisRepository implements ServerRepo } } } + return servers; } @@ -215,7 +229,6 @@ public class RedisServerRepository extends RedisRepository implements ServerRepo try { - System.out.println(data.toString()); ServerGroup serverGroup = new ServerGroup(data, serverStatuses); if (serverGroup.getRegion() == Region.ALL || serverGroup.getRegion() == getRegion()) @@ -247,6 +260,7 @@ public class RedisServerRepository extends RedisRepository implements ServerRepo String max = "+inf"; names = jedis.zrangeByScore(key, min, max); } + return names; } @@ -344,7 +358,7 @@ public class RedisServerRepository extends RedisRepository implements ServerRepo { String key = concatenate("servergroups", serverGroup); Map data = jedis.hgetAll(key); - System.out.println(data.toString()); + server = new ServerGroup(data, null); } diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/pom.xml b/Plugins[Modified]/Mineplex.ServerMonitor/pom.xml new file mode 100644 index 00000000..ce25de61 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + + com.mineplex + mineplex-app + dev-SNAPSHOT + ../app.xml + + + ServerMonitor + mineplex-servermonitor + + + UTF-8 + 2.12 + + + + + ${project.groupId} + mineplex-core-common + ${project.version} + + + ${project.groupId} + mineplex-serverdata + ${project.version} + + + org.apache.httpcomponents + httpclient + + + jline + jline + ${version.jline} + compile + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + mineplex.servermonitor.ServerMonitor + + + + + + + diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/CustomFormatter.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/CustomFormatter.java new file mode 100644 index 00000000..ad8d26bb --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/CustomFormatter.java @@ -0,0 +1,13 @@ +package mineplex.servermonitor; + +import java.util.logging.Formatter; +import java.util.logging.LogRecord; + +public class CustomFormatter extends Formatter +{ + @Override + public String format(LogRecord record) + { + return record.getMessage() + "\n"; + } +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/GenericRunnable.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/GenericRunnable.java new file mode 100644 index 00000000..2541be02 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/GenericRunnable.java @@ -0,0 +1,6 @@ +package mineplex.servermonitor; + +public interface GenericRunnable +{ + void run(T t); +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/JsonWebCall.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/JsonWebCall.java new file mode 100644 index 00000000..d0cf143f --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/JsonWebCall.java @@ -0,0 +1,357 @@ +package mineplex.servermonitor; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +import mineplex.core.common.util.Callback; + +public class JsonWebCall +{ + private String _url; + private PoolingClientConnectionManager _connectionManager; + + public JsonWebCall(String url) + { + _url = url; + + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + + _connectionManager = new PoolingClientConnectionManager(schemeRegistry); + _connectionManager.setMaxTotal(200); + _connectionManager.setDefaultMaxPerRoute(20); + } + + public String ExecuteReturnStream(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + result = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("Error executing ApiWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return result; + } + + public void Execute() + { + Execute((Object)null); + } + + public void Execute(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + + try + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + httpClient.execute(request); + } + catch (Exception ex) + { + System.out.println("ApiWebCall.Execute() Error:\n" + ex.getMessage()); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnType); + } + } + catch (Exception ex) + { + System.out.println("Error executing ApiWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public T Execute(Class returnClass, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnClass); + } + } + catch (Exception ex) + { + System.out.println("Error executing ApiWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public void Execute(Class callbackClass, Callback callback) + { + Execute(callbackClass, callback, (Object)null); + } + + public void Execute(Class callbackClass, Callback callback, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null && callback != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + callback.run(new Gson().fromJson(result, callbackClass)); + } + } + catch (Exception ex) + { + System.out.println("Error executing ApiWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPing.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPing.java new file mode 100644 index 00000000..e101cc0c --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPing.java @@ -0,0 +1,102 @@ +package mineplex.servermonitor; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import com.google.gson.Gson; + +public class MinecraftPing { + + /** + * Fetches a {@link MinecraftPingReply} for the supplied hostname. + * Assumed timeout of 2s and port of 25565. + * + * @param hostname - a valid String hostname + * @return {@link MinecraftPingReply} + * @throws IOException + */ + public MinecraftPingReply getPing(final String hostname) throws IOException { + return this.getPing(new MinecraftPingOptions().setHostname(hostname)); + } + + /** + * Fetches a {@link MinecraftPingReply} for the supplied options. + * + * @param options - a filled instance of {@link MinecraftPingOptions} + * @return {@link MinecraftPingReply} + * @throws IOException + */ + public MinecraftPingReply getPing(final MinecraftPingOptions options) throws IOException { + MinecraftPingUtil.validate(options.getHostname(), "Hostname cannot be null."); + MinecraftPingUtil.validate(options.getPort(), "Port cannot be null."); + + final Socket socket = new Socket(); + socket.connect(new InetSocketAddress(options.getHostname(), options.getPort()), options.getTimeout()); + + final DataInputStream in = new DataInputStream(socket.getInputStream()); + final DataOutputStream out = new DataOutputStream(socket.getOutputStream()); + + //> Handshake + + ByteArrayOutputStream handshake_bytes = new ByteArrayOutputStream(); + DataOutputStream handshake = new DataOutputStream(handshake_bytes); + + handshake.writeByte(MinecraftPingUtil.PACKET_HANDSHAKE); + MinecraftPingUtil.writeVarInt(handshake, MinecraftPingUtil.PROTOCOL_VERSION); + MinecraftPingUtil.writeVarInt(handshake, options.getHostname().length()); + handshake.writeBytes(options.getHostname()); + handshake.writeShort(options.getPort()); + MinecraftPingUtil.writeVarInt(handshake, MinecraftPingUtil.STATUS_HANDSHAKE); + + MinecraftPingUtil.writeVarInt(out, handshake_bytes.size()); + out.write(handshake_bytes.toByteArray()); + + //> Status request + + out.writeByte(0x01); // Size of packet + out.writeByte(MinecraftPingUtil.PACKET_STATUSREQUEST); + + //< Status response + + MinecraftPingUtil.readVarInt(in); // Size + int id = MinecraftPingUtil.readVarInt(in); + + MinecraftPingUtil.io(id == -1, "Server prematurely ended stream."); + MinecraftPingUtil.io(id != MinecraftPingUtil.PACKET_STATUSREQUEST, "Server returned invalid packet."); + + int length = MinecraftPingUtil.readVarInt(in); + MinecraftPingUtil.io(length == -1, "Server prematurely ended stream."); + MinecraftPingUtil.io(length == 0, "Server returned unexpected value."); + + byte[] data = new byte[length]; + in.readFully(data); + String json = new String(data, options.getCharset()); + + //> Ping + + out.writeByte(0x09); // Size of packet + out.writeByte(MinecraftPingUtil.PACKET_PING); + out.writeLong(System.currentTimeMillis()); + + //< Ping + + MinecraftPingUtil.readVarInt(in); // Size + id = MinecraftPingUtil.readVarInt(in); + MinecraftPingUtil.io(id == -1, "Server prematurely ended stream."); + //MinecraftPingUtil.io(id != MinecraftPingUtil.PACKET_PING, "Server returned invalid packet."); + + // Close + + handshake.close(); + handshake_bytes.close(); + out.close(); + in.close(); + socket.close(); + + return new Gson().fromJson(json, MinecraftPingReply.class); + } + +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingOptions.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingOptions.java new file mode 100644 index 00000000..1cbe0a4d --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingOptions.java @@ -0,0 +1,45 @@ +package mineplex.servermonitor; + +public class MinecraftPingOptions +{ + private String hostname; + private int port = 25565; + private int timeout = 2000; + private String charset = "UTF-8"; + + public MinecraftPingOptions setHostname(String hostname) { + this.hostname = hostname; + return this; + } + + public MinecraftPingOptions setPort(int port) { + this.port = port; + return this; + } + + public MinecraftPingOptions setTimeout(int timeout) { + this.timeout = timeout; + return this; + } + + public MinecraftPingOptions setCharset(String charset) { + this.charset = charset; + return this; + } + + public String getHostname() { + return this.hostname; + } + + public int getPort() { + return this.port; + } + + public int getTimeout() { + return this.timeout; + } + + public String getCharset() { + return this.charset; + } +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingReply.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingReply.java new file mode 100644 index 00000000..f6aecde3 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingReply.java @@ -0,0 +1,103 @@ +package mineplex.servermonitor; + +import java.util.List; + +public class MinecraftPingReply { + + private String description; + private Players players; + private Version version; + private String favicon; + + /** + * @return the MOTD + */ + public String getDescription() { + return this.description; + } + + public Players getPlayers() { + return this.players; + } + + /** + * @return @{link Version} + */ + public Version getVersion() { + return this.version; + } + + /** + * @return Base64 encoded favicon image + */ + public String getFavicon() { + return this.favicon; + } + + public class Players { + private int max; + private int online; + private List sample; + + /** + * @return Maximum player count + */ + public int getMax() { + return this.max; + } + + /** + * @return Online player count + */ + public int getOnline() { + return this.online; + } + + /** + * @return List of some players (if any) specified by server + */ + public List getSample() { + return this.sample; + } + } + + public class Player { + private String name; + private String id; + + /** + * @return Name of player + */ + public String getName() { + return this.name; + } + + /** + * @return Unknown + */ + public String getId() { + return this.id; + } + + } + + public class Version { + private String name; + private int protocol; + + /** + * @return Version name (ex: 13w41a) + */ + public String getName() { + return this.name; + } + + /** + * @return Protocol version + */ + public int getProtocol() { + return this.protocol; + } + } + +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingUtil.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingUtil.java new file mode 100644 index 00000000..11a01db5 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/MinecraftPingUtil.java @@ -0,0 +1,63 @@ +package mineplex.servermonitor; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class MinecraftPingUtil { + + public static byte PACKET_HANDSHAKE = 0x00, PACKET_STATUSREQUEST = 0x00, PACKET_PING = 0x01; + public static int PROTOCOL_VERSION = 4; + public static int STATUS_HANDSHAKE = 1; + + public static void validate(final Object o, final String m) + { + if (o == null) + { + throw new RuntimeException(m); + } + } + + public static void io(final boolean b, final String m) throws IOException + { + if (b) + { + throw new IOException(m); + } + } + + public static int readVarInt(DataInputStream in) throws IOException + { + int i = 0; + int j = 0; + while (true) { + int k = in.readByte(); + + i |= (k & 0x7F) << j++ * 7; + + if (j > 5) + throw new RuntimeException("VarInt too big"); + + if ((k & 0x80) != 128) + break; + } + + return i; + } + + public static void writeVarInt(DataOutputStream out, int paramInt) throws IOException + { + while (true) + { + if ((paramInt & 0xFFFFFF80) == 0) + { + out.writeByte(paramInt); + return; + } + + out.writeByte(paramInt & 0x7F | 0x80); + paramInt >>>= 7; + } + } + +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ProcessRunner.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ProcessRunner.java new file mode 100644 index 00000000..6e2056ca --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ProcessRunner.java @@ -0,0 +1,81 @@ +package mineplex.servermonitor; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class ProcessRunner extends Thread +{ + private ProcessBuilder _processBuilder; + private Process _process; + private GenericRunnable _runnable; + + boolean _done = false; + Boolean _error = false; + + ProcessRunner(String[] args) + { + super("ProcessRunner " + args); + _processBuilder = new ProcessBuilder(args); + } + + public void run() + { + try + { + _process = _processBuilder.start(); + _process.waitFor(); + + BufferedReader reader=new BufferedReader(new InputStreamReader(_process.getInputStream())); + String line = reader.readLine(); + + while(line != null) + { + if (line.equals("255")) + _error = true; + + line=reader.readLine(); + } + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + finally + { + _done = true; + + if (_runnable != null) + _runnable.run(_error); + } + } + + public void start(GenericRunnable runnable) + { + super.start(); + + _runnable = runnable; + } + + public int exitValue() throws IllegalStateException + { + if (_process != null) + { + return _process.exitValue(); + } + + throw new IllegalStateException("Process not started yet"); + } + + public boolean isDone() + { + return _done; + } + + public void abort() + { + if (!isDone()) + { + _process.destroy(); + } + } + } diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java new file mode 100644 index 00000000..7650caac --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java @@ -0,0 +1,952 @@ +package mineplex.servermonitor; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Timer; +import java.util.TimerTask; +import java.util.logging.FileHandler; +import java.util.logging.Logger; + +import com.google.common.base.Throwables; +import org.fusesource.jansi.AnsiConsole; + +import mineplex.core.common.util.NautHashMap; +import mineplex.serverdata.Region; +import mineplex.serverdata.commands.RestartCommand; +import mineplex.serverdata.commands.SuicideCommand; +import mineplex.serverdata.data.DedicatedServer; +import mineplex.serverdata.data.MinecraftServer; +import mineplex.serverdata.data.ServerGroup; +import mineplex.serverdata.servers.DedicatedServerSorter; +import mineplex.serverdata.servers.ServerManager; +import mineplex.serverdata.servers.ServerRepository; + +import jline.console.ConsoleReader; + +public class ServerMonitor +{ + private static volatile ServerRepository _repository = null; + private static StatusHistoryRepository _historyRepository = null; + private static int _count = 0; + private static HashSet _processes = new HashSet(); + private static HashMap _badServers = new HashMap(); + private static Collection _serverStatuses = null; + private static Collection _serverGroups = null; + private static Map _serverGroupMap = null; + private static volatile List _dedicatedServers = null; + private static HashSet _deadServers = new HashSet(); + private static HashSet _delayedKill = new HashSet(); + private static HashSet _laggyServers = new HashSet(); + + private static final SimpleDateFormat _dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + private static final Logger _logger = Logger.getLogger("ServerMonitor"); + private static Timer _timer = new Timer(); + + private static int _totalPlayers = 0; + private static Region _region; + + private static boolean _debug = false; + + public static void main (String args[]) + { + /* + MinecraftPingReply data = null; + try + { + data = new MinecraftPing().getPing(new MinecraftPingOptions().setHostname("127.0.0.1").setPort(25565)); + } + catch (IOException e2) + { + e2.printStackTrace(); + } + System.out.println(data.getDescription() + " " + data.getPlayers().getOnline()); + */ + _region = !new File("eu.dat").exists() ? Region.US : Region.EU; + _debug = new File("debug.dat").exists(); + _repository = ServerManager.getServerRepository(_region); // Fetches and connects to server repo + _historyRepository = new StatusHistoryRepository(); + File logFile = new File("monitor.log"); + + if (!logFile.exists()) + { + try + { + logFile.createNewFile(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + + try + { + FileHandler fileHandler = new FileHandler("monitor.log", true); + fileHandler.setFormatter(new CustomFormatter()); + _logger.addHandler(fileHandler); + _logger.setUseParentHandlers(false); + } + catch (SecurityException | IOException e1) + { + e1.printStackTrace(); + } + + new Thread(new Runnable() + { + @Override + public void run() + { + try + { + AnsiConsole.systemInstall(); + ConsoleReader reader = new ConsoleReader(); + reader.setExpandEvents(false); + + String command; + while ((command = reader.readLine(">")) != null) + { + if (command.contains("printservers")) + { + String[] parts = command.split(" "); + String serverGroup = ""; + if (parts.length > 1) + { + serverGroup = parts[1]; + } + + printServersCommand(serverGroup); + } + else if (command.equals("help")) + { + log("Commands:"); + log("printservers (server-group) - prints all servers if no server group is" + + "supplied, or all servers of a given group if a server group is supplied."); + } + else + { + log("No command " + command + " found."); + } + } + } + catch (Exception e) + { + log(Throwables.getStackTraceAsString(e)); + } + } + }).start(); + + HashMap> serverTracker = new HashMap>(); + + while (true) + { + try + { + _totalPlayers = 0; + _serverStatuses = _repository.getServerStatuses(); + _serverGroups = _repository.getServerGroups(_serverStatuses); + _serverGroupMap = new HashMap(); + _dedicatedServers = Collections.synchronizedList(new ArrayList<>(_repository.getDedicatedServers())); + + calculateTotalPlayers(); + killDeadServers(); + + double totalCPU = 0.0; + double totalRAM = 0.0; + double availableCPU = 0.0; + double availableRAM = 0.0; + + for (DedicatedServer server : _dedicatedServers) + { + totalCPU += server.getAvailableCpu(); + totalRAM += server.getAvailableRam(); + } + + for (MinecraftServer minecraftServer : _serverStatuses) + { + if (!ignoreServer(minecraftServer.getGroup())) + { + if (minecraftServer.getMotd().contains("Finished") || (minecraftServer.getGroup().equalsIgnoreCase("UltraHardcore") && minecraftServer.getMotd().contains("Restarting") && minecraftServer.getPlayerCount() == 0)) + { + killServer(minecraftServer.getName(), minecraftServer.getPublicAddress(), minecraftServer.getPlayerCount(), "[KILLED] [FINISHED] " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress(), true); + + handleUserServerGroup(_serverGroupMap.get(minecraftServer.getGroup())); + continue; + } + } + + for (DedicatedServer server : _dedicatedServers) + { + if (_serverGroupMap.containsKey(minecraftServer.getGroup()) && minecraftServer.getPublicAddress().equalsIgnoreCase(server.getPrivateAddress())) + { + ServerGroup serverGroup = _serverGroupMap.get(minecraftServer.getGroup()); + server.incrementServerCount(serverGroup); + } + } + } + + if (_count % 15 == 0) + { + _badServers.clear(); + + for (DedicatedServer serverData : _dedicatedServers) + { + if (isServerOffline(serverData)) + { + log("------=[OFFLINE]=------=[" + serverData.getName() + ":" + serverData.getPublicAddress() + "]=------=[OFFLINE]=------"); + _badServers.put(serverData.getName(), true); + } + } + + log(_badServers.size() + " bad servers."); + } + + for (Iterator iterator = _dedicatedServers.iterator(); iterator.hasNext();) + { + DedicatedServer serverData = iterator.next(); + + if (_badServers.containsKey(serverData.getName())) + iterator.remove(); + else + { + availableCPU += serverData.getAvailableCpu(); + availableRAM += serverData.getAvailableRam(); + } + } + + double usedCpuPercent = Math.round((1 - availableCPU / totalCPU) * 10000.0) / 100.0; + double usedRamPercent = Math.round((1 - availableRAM / totalRAM) * 10000.0) / 100.0; + + log("Using " + usedCpuPercent + "% of available CPU (" + availableCPU + " Free) and " + usedRamPercent + "% of available RAM (" + availableRAM / 1000 + "GB Free)"); + + try + { + _historyRepository.saveDedicatedServerStats(_dedicatedServers); + log("Saved Dedicated Server Stats."); + _historyRepository.saveServerGroupStats((int)totalCPU, (int)totalRAM, _serverGroupMap.values()); + log("Saved ServerGroup Stats."); + _historyRepository.saveNetworkStats(usedCpuPercent, usedRamPercent, availableCPU, availableRAM, _region); + log("Saved Network Stats."); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + if (_count == 0) + { + for (Iterator groupStatusIterator = _serverGroups.iterator(); groupStatusIterator.hasNext();) + { + ServerGroup groupStatus = groupStatusIterator.next(); + + if (groupStatus.getServerType().equalsIgnoreCase("Player")) + { + _repository.removeServerGroup(groupStatus); + _serverGroupMap.remove(groupStatus.getName()); + groupStatusIterator.remove(); + + System.out.println("Removed MPS : " + groupStatus.getName()); + } + if (groupStatus.getServerType().equalsIgnoreCase("Community")) + { + _repository.removeServerGroup(groupStatus); + _serverGroupMap.remove(groupStatus.getName()); + groupStatusIterator.remove(); + + System.out.println("Removed MCS : " + groupStatus.getName()); + } + } + } + + for (ServerGroup groupStatus : _serverGroups) + { + if (ignoreServer(groupStatus.getName())) + continue; + + NautHashMap serverMap = new NautHashMap(); + + for (Iterator serverIterator = groupStatus.getServers().iterator(); serverIterator.hasNext();) + { + try + { + MinecraftServer server = serverIterator.next(); + String[] nameArgs = server.getName().split("-"); + int serverNum = Integer.parseInt(nameArgs[nameArgs.length - 1]); + + if (serverMap.containsKey(serverNum)) + { + killServer(server.getName(), server.getPublicAddress(), server.getPlayerCount(), "[KILLED] [DUPLICATE] " + server.getName() + ":" + server.getPublicAddress(), true); + serverIterator.remove(); + } + else + { + serverMap.put(serverNum, server); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + } + } + + HashSet onlineServers = new HashSet(); + HashSet laggyServers = new HashSet(); + laggyServers.addAll(_laggyServers); + _laggyServers.clear(); + + for (MinecraftServer minecraftServer : _serverStatuses) + { + if (ignoreServer(minecraftServer.getGroup())) + continue; + + onlineServers.add(minecraftServer.getName()); + + if (minecraftServer.getTps() <= 17) + { + if (minecraftServer.getTps() <= 10) + { + if (laggyServers.contains(minecraftServer.getName())) + { + new RestartCommand(minecraftServer.getName(), _region, false).publish(); + log("[RESTART LAGGY] : " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress()); + } + else + { + _laggyServers.add(minecraftServer.getName()); + log("[IMPENDING RESTART LAGGY] : " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress()); + } + } + else + log("[Performance] " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress() + "] Running poorly at " + minecraftServer.getTps() + " TPS"); + } + } + + for (Iterator>> iterator = serverTracker.entrySet().iterator(); iterator.hasNext();) + { + Entry> entry = iterator.next(); + + if (onlineServers.contains(entry.getKey())) + iterator.remove(); + else if (System.currentTimeMillis() - entry.getValue().getValue() > 35000) + { + String serverName = entry.getKey(); + String serverAddress = entry.getValue().getKey(); + killServer(serverName, serverAddress, 0, "[KILLED] [SLOW-STARTUP] " + serverName + ":" + serverAddress, true); + iterator.remove(); + } + } + + for (ServerGroup serverGroup : _serverGroups) + { + if (ignoreServer(serverGroup.getName())) + continue; + + try + { + handleGroupChanges(serverTracker, serverGroup, false); + } + catch (Exception exception) + { + log(exception.getMessage()); + log("Can't handle group changes for " + serverGroup.getName()); + } + } + + int processWaits = 0; + + while (_processes.size() > 0) + { + try + { + for (Iterator iterator = _processes.iterator(); iterator.hasNext();) + { + ProcessRunner pr = iterator.next(); + + try + { + pr.join(100); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + if (pr.isDone()) + iterator.remove(); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + if (_processes.size() > 0) + { + try + { + log("Sleeping while processes run..."); + Thread.sleep(6000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + if (processWaits >= 5) + { + log("Killing stale processes."); + + for (Iterator iterator = _processes.iterator(); iterator.hasNext();) + { + iterator.next().abort(); + iterator.remove(); + } + + _processes.clear(); + } + + processWaits++; + } + + processWaits = 0; + + try + { + log("Natural sleep."); + Thread.sleep(10000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + _count++; + } + catch (Exception ex) + { + log("Error doing something : " + ex.getMessage()); + ex.printStackTrace(); + try + { + Thread.sleep(1000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } + } + + private static void killDeadServers() + { + HashSet deadServers = new HashSet(); + deadServers.addAll(_deadServers); + + _deadServers.clear(); + for (final MinecraftServer deadServer : _repository.getDeadServers()) + { + if (deadServer.getUptime() <= 10 || ignoreServer(deadServer.getGroup())) + continue; + + try + { + if (_count == 0 || deadServers.contains(deadServer.getName())) + { + if (_count != 0) + copyServerLog(deadServer); + + killServer(deadServer.getName(), deadServer.getPublicAddress(), deadServer.getPlayerCount(), "[KILLED] [DEAD] " + deadServer.getName() + ":" + deadServer.getPublicAddress(), true); + + handleUserServerGroup(_serverGroupMap.get(deadServer.getGroup())); + } + else if (!_delayedKill.contains(deadServer.getName())) + { + startTimingReport(deadServer); + + _timer.schedule(new TimerTask() + { + @Override + public void run() + { + _deadServers.add(deadServer.getName()); + _delayedKill.remove(deadServer.getName()); + + stopTimingReport(deadServer); + log("[IMPENDING DEATH] : " + deadServer.getName() + ":" + deadServer.getPublicAddress()); + } + }, 20 * 1000); + + _delayedKill.add(deadServer.getName()); + } + } + catch (Exception exception) + { + log("[ERROR] : Trying to delete " + deadServer.getName() + ":" + deadServer.getPublicAddress()); + exception.printStackTrace(); + } + } + } + + private static void handleUserServerGroup(ServerGroup serverGroup) + { + if (serverGroup != null && serverGroup.getHost() != null && !serverGroup.getHost().isEmpty() && serverGroup.getServerCount() <= 1) + { + _repository.removeServerGroup(serverGroup); + _serverGroupMap.remove(serverGroup.getName()); + _serverGroups.remove(serverGroup); + System.out.println("Removed ServerGroup : " + serverGroup.getName()); + } + } + + private static void calculateTotalPlayers() + { + for (ServerGroup serverGroup : _serverGroups) + { + _serverGroupMap.put(serverGroup.getName(), serverGroup); + _totalPlayers += serverGroup.getPlayerCount(); + } + + log("Total Players : " + _totalPlayers); + } + + private static void handleGroupChanges(HashMap> serverTracker, ServerGroup serverGroup, boolean free) + { + int serverNum = 0; + int requiredTotal = serverGroup.getRequiredTotalServers(); + int requiredJoinable = serverGroup.getRequiredJoinableServers(); + int joinableServers = serverGroup.getJoinableCount(); + int totalServers = serverGroup.getServerCount(); + int serversToAdd = Math.max(0, Math.max(requiredTotal - totalServers, requiredJoinable - joinableServers)); + int serversToKill = (totalServers > requiredTotal && joinableServers > requiredJoinable) ? Math.min(joinableServers - requiredJoinable, serverGroup.getEmptyServers().size()) : 0; + int serversToRestart = 0; + + // Minimum 1500 slot bufferzone + if (serverGroup.getName().equalsIgnoreCase("Lobby")) + { + if (_region == Region.EU) + { + requiredTotal = 10; + requiredJoinable = 10; + } + + int availableSlots = serverGroup.getMaxPlayerCount() - serverGroup.getPlayerCount(); + + if (availableSlots < 1000) + { + serversToAdd = Math.max(1, (1000 - availableSlots) / serverGroup.getMaxPlayers()); + serversToAdd = Math.min(250 - totalServers, serversToAdd); + serversToKill = 0; + } + else if (serversToKill > 0) + serversToKill = Math.min(serversToKill, (availableSlots - 1000) / 80); + else if (serversToAdd == 0 && joinableServers > requiredJoinable && totalServers > requiredTotal) + { + serversToRestart = Math.min(joinableServers - requiredJoinable, joinableServers - requiredTotal); + serversToRestart = Math.min(serversToRestart, (availableSlots - 1000) / 80); + + if (serversToRestart <= 5) + serversToRestart = 0; + } + + + } + else if (serverGroup.getName().equalsIgnoreCase("Halloween")) + { + if (serverGroup.getServers().size() > (_region == Region.US ? 300 : 100)) + { + serversToAdd = 0; + } + } + else if (serverGroup.getName().equalsIgnoreCase("Christmas")) + { + if (serverGroup.getServers().size() > (_region == Region.US ? 300 : 100)) + { + serversToAdd = 0; + } + } + else if (serverGroup.getName().equalsIgnoreCase("UltraHardcore")) + { + int maxUHC = Math.max(1, _totalPlayers / 6000); + + if (serversToAdd > 0) + serversToAdd = maxUHC - joinableServers; + + if (joinableServers > maxUHC) + serversToKill = maxUHC - joinableServers; + } + else if (ignoreServer(serverGroup.getName())) + { + return; + } + + // KILL, CLEAN, THEN ADD + while (serversToKill > 0) + { + List emptyServers = new ArrayList(serverGroup.getEmptyServers()); + MinecraftServer emptyServer = emptyServers.get(serversToKill - 1); + killServer(emptyServer, "[KILLED] [EXCESS] " + emptyServer.getName() + ":" + emptyServer.getPublicAddress()); + serversToKill--; + } + + while (serversToAdd > 0) + { + serverNum = serverGroup.generateUniqueId(serverNum + 1); + + while (_deadServers.contains(serverGroup.getPrefix() + "-" + serverNum)) + { + serverNum = serverGroup.generateUniqueId(serverNum + 1); + } + + Collections.sort(_dedicatedServers, new DedicatedServerSorter()); + DedicatedServer bestServer = getBestDedicatedServer(_dedicatedServers, serverGroup); + + if (bestServer == null) + { + log("!!!!!!!!!!!!!!!!!!!!!!!!!!!! NO DEDICATED SERVER AVAILABLE FOR GROUP " + serverGroup.getName() + " !!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + break; + } + + if (serverTracker.containsKey(serverGroup.getPrefix() + "-" + serverNum)) + log("[WAITING] On " + serverGroup.getPrefix() + "-" + serverNum + " to finish starting..."); + else + { + startServer(bestServer, serverGroup, serverNum, free); + serverTracker.put(serverGroup.getPrefix() + "-" + serverNum, new AbstractMap.SimpleEntry(bestServer.getPublicAddress(), System.currentTimeMillis())); + } + + serversToAdd--; + } + + List servers = new ArrayList(); + servers.addAll(serverGroup.getServers()); + Collections.sort(servers, new ServerSorter()); + + while (serversToRestart > 0) + { + MinecraftServer server = servers.get(servers.size() - serversToRestart); + new SuicideCommand(server.getName(), _region).publish(); + log("[RESTART/KILL EXCESS] : " + server.getName() + ":" + server.getPublicAddress() + " " + server.getPlayerCount() + " players"); + serversToRestart--; + } + } + + private static void killServer(final String serverName, final String serverAddress, final int players, final String message, final boolean announce) + { + if (_debug) + return; + + String cmd = "/home/mineplex/easyRemoteKillServer.sh"; + + ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverName}); + pr.start(new GenericRunnable() + { + @Override + public void run(Boolean error) + { + MinecraftServer server = null; + + if (!error) + { + server = _repository.getServerStatus(serverName); + + if (server != null) + { + _repository.removeServerStatus(server); + } + } + + if (announce) + { + if (error) + log("[" + serverName + ":" + serverAddress + "] Kill errored."); + else + log(message + " Players: " + players); + } + } + }); + + try + { + pr.join(50); + } + catch (InterruptedException e1) + { + e1.printStackTrace(); + } + + + if (!pr.isDone()) + _processes.add(pr); + } + + private static boolean isServerOffline(DedicatedServer serverData) + { + boolean success = false; + + if (_debug) + return false; + + Process process = null; + String cmd = "/home/mineplex/isServerOnline.sh"; + + ProcessBuilder processBuilder = new ProcessBuilder(new String[] {"/bin/sh", cmd, serverData.getPublicAddress()}); + + try + { + process = processBuilder.start(); + process.waitFor(); + + BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream())); + String line = reader.readLine(); + + while(line != null) + { + success = line.equals("Success"); + + line=reader.readLine(); + } + } + catch (Exception e1) + { + e1.printStackTrace(); + } + finally + { + process.destroy(); + } + + return !success; + } + + private static DedicatedServer getBestDedicatedServer(Collection dedicatedServers, ServerGroup serverGroup) + { + DedicatedServer bestServer = null; + + for (DedicatedServer serverData : dedicatedServers) + { + if (serverData.getAvailableRam() > serverGroup.getRequiredRam() + && serverData.getAvailableCpu() > serverGroup.getRequiredCpu()) + { + if (bestServer == null || serverData.getServerCount(serverGroup) < bestServer.getServerCount(serverGroup)) + { + bestServer = serverData; + } + } + } + + return bestServer; + } + + private static void killServer(final MinecraftServer serverToKill, String message) + { + killServer(serverToKill.getName(), serverToKill.getPublicAddress(), serverToKill.getPlayerCount(), message, true); + } + + private static void startTimingReport(final MinecraftServer server) + { + if (_debug) + return; + + String cmd = "/home/mineplex/remoteStartTiming.sh"; + + ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() }); + pr.start(new GenericRunnable() + { + @Override + public void run(Boolean error) + { + if (error) + log("[TIMING START] Errored " + server.getName() + "(" + server.getPublicAddress() + ")"); + else + log("[TIMING START] Succeeded " + server.getName() + "(" + server.getPublicAddress() + ")"); + + } + }); + + try + { + pr.join(100); + } + catch (InterruptedException e1) + { + e1.printStackTrace(); + } + + if (!pr.isDone()) + _processes.add(pr); + } + + private static void stopTimingReport(final MinecraftServer server) + { + if (_debug) + return; + + String cmd = "/home/mineplex/remoteStopTiming.sh"; + + ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() }); + pr.start(new GenericRunnable() + { + @Override + public void run(Boolean error) + { + if (error) + log("[TIMING PASTE] Errored " + server.getName() + "(" + server.getPublicAddress() + ")"); + else + log("[TIMING PASTE] Succeeded " + server.getName() + "(" + server.getPublicAddress() + ")"); + + } + }); + + try + { + pr.join(100); + } + catch (InterruptedException e1) + { + e1.printStackTrace(); + } + + if (!pr.isDone()) + _processes.add(pr); + } + + private static void copyServerLog(final MinecraftServer server) + { + if (_debug) + return; + + String cmd = "/home/mineplex/easyRemoteCopyLog.sh"; + + ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() }); + pr.start(new GenericRunnable() + { + @Override + public void run(Boolean error) + { + if (error) + log("[COPY LOG] Errored " + server.getName() + "(" + server.getPublicAddress() + ")"); + else + log("[COPY LOG] Succeeded " + server.getName() + "(" + server.getPublicAddress() + ")"); + + } + }); + + try + { + pr.join(100); + } + catch (InterruptedException e1) + { + e1.printStackTrace(); + } + + if (!pr.isDone()) + _processes.add(pr); + } + + private static void startServer(final DedicatedServer serverSpace, final ServerGroup serverGroup, final int serverNum, final boolean free) + { + if (_debug) + return; + + String cmd = "/home/mineplex/easyRemoteStartServerCustom.sh"; + final String groupPrefix = serverGroup.getPrefix(); + final String serverName = serverSpace.getName(); + final String serverAddress = serverSpace.getPublicAddress(); + + ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverSpace.getPrivateAddress(), (serverGroup.getPortSection() + serverNum) + "", serverGroup.getRequiredRam() + "", serverGroup.getWorldZip(), serverGroup.getPlugin(), serverGroup.getConfigPath(), serverGroup.getName(), serverGroup.getPrefix() + "-" + serverNum, serverSpace.isUsRegion() ? "true" : "false", serverGroup.getAddNoCheat() + "", serverGroup.getAddWorldEdit() + "" }); + pr.start(new GenericRunnable() + { + @Override + public void run(Boolean error) + { + if (error) + log("[" + serverName + ":" + serverAddress + " Free Resources; CPU " + serverSpace.getAvailableCpu() + " RAM " + serverSpace.getAvailableRam() + "MB] Errored " + serverName + "(" + groupPrefix+ "-" + serverNum + (free ? "-FREE" : "") + ")"); + else + log("[" + serverName + ":" + serverAddress + " Free Resources; CPU " + serverSpace.getAvailableCpu() + " RAM " + serverSpace.getAvailableRam() + "MB] Added " + serverName + "(" + groupPrefix+ "-" + serverNum + (free ? "-FREE" : "") + ")"); + + } + }); + + try + { + pr.join(100); + } + catch (InterruptedException e1) + { + e1.printStackTrace(); + } + + serverSpace.incrementServerCount(serverGroup); + + if (!pr.isDone()) + _processes.add(pr); + } + + private static void printServersCommand(String serverGroup) + { + // grab servers + Collection servers = _repository.getServerStatuses(); + + // remove entries not within the target server group, if one is supplied + if (!serverGroup.isEmpty()) + { + servers.removeIf(s -> !s.getGroup().equalsIgnoreCase(serverGroup)); + } + + List serverList = new ArrayList<>(servers); + Collections.sort(serverList, + (a, b) -> Integer.compare(b.getPlayerCount(), a.getPlayerCount())); + + serverList.forEach(server -> + { + Optional opt = getDediStatusFromAddress(server.getPublicAddress()); + String dediName = opt.map(dedi -> dedi.getName()).orElse("???"); + + String fmt = "%s: %s (%s players online), open slots: %s, free ram: %sMB"; + log(String.format(fmt, server.getName(), dediName, server.getPlayerCount(), + server.getMaxPlayerCount() - server.getPlayerCount(), server.getRam())); + }); + } + + private static Optional getDediStatusFromAddress(String address) + { + return _dedicatedServers.stream().filter(dedi -> dedi.getPrivateAddress().equals(address)) + .findFirst(); + } + + private static boolean ignoreServer(String serverGroupName) + { + return serverGroupName.equalsIgnoreCase("Testing") || serverGroupName.equalsIgnoreCase("Clans"); + } + + private static void log(String message) + { + log(message, false); + } + + private static void log(String message, boolean fileOnly) + { + _logger.info("[" + _dateFormat.format(new Date()) + "] " + message); + + if (!fileOnly) + System.out.println("[" + _dateFormat.format(new Date()) + "] " + message); + } +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerSorter.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerSorter.java new file mode 100644 index 00000000..dd97c296 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerSorter.java @@ -0,0 +1,21 @@ +package mineplex.servermonitor; + +import java.util.Comparator; + +import mineplex.serverdata.data.MinecraftServer; + +public class ServerSorter implements Comparator +{ + @Override + public int compare(MinecraftServer first, MinecraftServer second) + { + String[] args1 = first.getName().split("-"); + String[] args2 = second.getName().split("-"); + if (Integer.parseInt(args1[args1.length - 1]) < Integer.parseInt(args2[args2.length - 1])) + return -1; + else if (Integer.parseInt(args2[args2.length - 1]) < Integer.parseInt(args1[args1.length - 1])) + return 1; + + return 0; + } +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/StatusHistoryRepository.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/StatusHistoryRepository.java new file mode 100644 index 00000000..9b293056 --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/StatusHistoryRepository.java @@ -0,0 +1,263 @@ +package mineplex.servermonitor; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import mineplex.serverdata.Region; +import mineplex.serverdata.data.BungeeServer; +import mineplex.serverdata.data.DataRepository; +import mineplex.serverdata.data.DedicatedServer; +import mineplex.serverdata.data.ServerGroup; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; + +public class StatusHistoryRepository extends RepositoryBase +{ + private static String CREATE_GROUP_TABLE = "CREATE TABLE IF NOT EXISTS ServerGroupStats (id INT NOT NULL AUTO_INCREMENT, serverGroup VARCHAR(100), updated LONG, players INT, maxPlayers INT, totalNetworkCpuUsage DOUBLE(4,2), totalNetworkRamUsage DOUBLE(4,2), totalCpu MEDIUMINT, totalRam MEDIUMINT, US BOOLEAN NOT NULL DEFAULT '1', PRIMARY KEY (id));"; + private static String CREATE_DEDICATED_TABLE = "CREATE TABLE IF NOT EXISTS DedicatedServerStats (id INT NOT NULL AUTO_INCREMENT, serverName VARCHAR(100), address VARCHAR(25), updated LONG, cpu TINYINT, ram MEDIUMINT, usedCpuPercent DOUBLE(4,2), usedRamPercent DOUBLE(4,2), US BOOLEAN NOT NULL DEFAULT '1', PRIMARY KEY (id));"; + private static String CREATE_BUNGEE_TABLE = "CREATE TABLE IF NOT EXISTS BungeeStats (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(25), updated LONG, players INT, maxPlayers INT, alive BOOLEAN NOT NULL, online BOOLEAN NOT NULL, US BOOLEAN NOT NULL DEFAULT '1', PRIMARY KEY (id));"; + private static String CREATE_NETWORKSTATS_TABLE = "CREATE TABLE IF NOT EXISTS NetworkStats (id INT NOT NULL AUTO_INCREMENT, updated LONG, players INT, totalNetworkCpuUsage DOUBLE(4,2), totalNetworkRamUsage DOUBLE(4,2), totalCpu MEDIUMINT, totalRam MEDIUMINT, US BOOLEAN NOT NULL DEFAULT '1', PRIMARY KEY (id));"; + + private static String INSERT_SERVERGROUP_STATS = "INSERT INTO ServerGroupStats (serverGroup, updated, players, maxPlayers, totalNetworkCpuUsage, totalNetworkRamUsage, totalCpu, totalRam, US) VALUES (?, now(), ?, ?, ?, ?, ?, ?, ?);"; + private static String INSERT_DEDICATEDSERVER_STATS = "INSERT INTO DedicatedServerStats (serverName, address, updated, cpu, ram, usedCpuPercent, usedRamPercent, US) VALUES (?, ?, now(), ?, ?, ?, ?, ?);"; + private static String INSERT_BUNGEE_STATS = "INSERT INTO BungeeStats (address, updated, players, maxPlayers, alive, online, US) VALUES (?, now(), ?, ?, ?, ?, ?);"; + private static String INSERT_NETWORK_STATS = "INSERT INTO NetworkStats (updated, players, totalNetworkCpuUsage, totalNetworkRamUsage, totalCpu, totalRam, US) VALUES (now(), ?, ?, ?, ?, ?, ?);"; + + private static DataRepository _repository; + + public StatusHistoryRepository() + { + super(DBPool.getServerStats()); + + PreparedStatement preparedStatement = null; + + try(Connection connection = getConnection()) + { + // Create table + preparedStatement = connection.prepareStatement(CREATE_GROUP_TABLE); + preparedStatement.execute(); + preparedStatement.close(); + + // Create table + preparedStatement = connection.prepareStatement(CREATE_DEDICATED_TABLE); + preparedStatement.execute(); + preparedStatement.close(); + + // Create table + preparedStatement = connection.prepareStatement(CREATE_BUNGEE_TABLE); + preparedStatement.execute(); + preparedStatement.close(); + + // Create table + preparedStatement = connection.prepareStatement(CREATE_NETWORKSTATS_TABLE); + preparedStatement.execute(); + preparedStatement.close(); + + _repository = new RedisDataRepository(ServerManager.getConnection(true, ServerManager.SERVER_STATUS_LABEL), ServerManager.getConnection(false, ServerManager.SERVER_STATUS_LABEL), + Region.ALL, BungeeServer.class, "bungeeServers"); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void saveServerGroupStats(int totalCpu, int totalRam, Collection collection) + { + PreparedStatement preparedStatement = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(INSERT_SERVERGROUP_STATS); + + for (ServerGroup serverGroup : collection) + { + int serverCpu = serverGroup.getServerCount() * serverGroup.getRequiredCpu(); + int serverRam = serverGroup.getServerCount() * serverGroup.getRequiredRam(); + + preparedStatement.setString(1, serverGroup.getName()); + preparedStatement.setInt(2, serverGroup.getPlayerCount()); + preparedStatement.setInt(3, serverGroup.getMaxPlayerCount()); + preparedStatement.setDouble(4, (double)serverCpu / (double)totalCpu * 100d); + preparedStatement.setDouble(5, (double)serverRam / (double)totalRam * 100d); + preparedStatement.setInt(6, serverCpu); + preparedStatement.setInt(7, serverRam); + preparedStatement.setBoolean(8, serverGroup.getRegion() == Region.US); + preparedStatement.addBatch(); + } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void saveDedicatedServerStats(List dedicatedServers) + { + PreparedStatement preparedStatement = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(INSERT_DEDICATEDSERVER_STATS); + + for (DedicatedServer dedicatedServer : dedicatedServers) + { + double usedCpu = dedicatedServer.getMaxCpu() == 0 ? 0 : (1d - (double)dedicatedServer.getAvailableCpu() / (double)dedicatedServer.getMaxCpu()) * 100d; + double usedRam = dedicatedServer.getMaxRam() == 0 ? 0 : (1d - (double)dedicatedServer.getAvailableRam() / (double)dedicatedServer.getMaxRam()) * 100d; + + preparedStatement.setString(1, dedicatedServer.getName()); + preparedStatement.setString(2, dedicatedServer.getPrivateAddress()); + preparedStatement.setInt(3, dedicatedServer.getMaxCpu()); + preparedStatement.setInt(4, dedicatedServer.getMaxRam()); + preparedStatement.setDouble(5, usedCpu); + preparedStatement.setDouble(6, usedRam); + preparedStatement.setBoolean(7, dedicatedServer.getRegion() == Region.US); + preparedStatement.addBatch(); + } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void saveNetworkStats(double usedCpuPercent, double usedRamPercent, double availableCPU, double availableRAM, Region region) + { + int totalPlayers = 0; + + List bungeeServers = new ArrayList(_repository.getElements()); + + for (Iterator bungeeIterator = bungeeServers.iterator(); bungeeIterator.hasNext();) + { + BungeeServer server = bungeeIterator.next(); + + if (server.getPublicAddress().equalsIgnoreCase("127.0.0.1") || server.getPublicAddress().equalsIgnoreCase("0.0.0.0")) + bungeeIterator.remove(); + } + + PreparedStatement preparedStatement = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(INSERT_BUNGEE_STATS); + + for (BungeeServer bungeeStatusData : bungeeServers) + { + totalPlayers += bungeeStatusData.getPlayerCount(); + preparedStatement.setString(1, bungeeStatusData.getPublicAddress()); + preparedStatement.setInt(2, bungeeStatusData.getPlayerCount()); + preparedStatement.setInt(3, bungeeStatusData.getPlayerCount()); + preparedStatement.setBoolean(4, true); + preparedStatement.setBoolean(5, true); + preparedStatement.setBoolean(6, bungeeStatusData.getRegion() == Region.US); + preparedStatement.addBatch(); + } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + preparedStatement = null; + + try(Connection connection = getConnection()) + { + preparedStatement = connection.prepareStatement(INSERT_NETWORK_STATS); + preparedStatement.setInt(1, totalPlayers); + preparedStatement.setDouble(2, usedCpuPercent); + preparedStatement.setDouble(3, usedRamPercent); + preparedStatement.setInt(4, (int)availableCPU); + preparedStatement.setInt(5, (int)availableRAM); + preparedStatement.setBoolean(6, region == Region.US); + + preparedStatement.executeUpdate(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } +} diff --git a/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/data/BungeeStatusData.java b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/data/BungeeStatusData.java new file mode 100644 index 00000000..dee4771f --- /dev/null +++ b/Plugins[Modified]/Mineplex.ServerMonitor/src/mineplex/servermonitor/data/BungeeStatusData.java @@ -0,0 +1,11 @@ +package mineplex.servermonitor.data; + +public class BungeeStatusData +{ + public int Players; + public int MaxPlayers; + public String Address; + public boolean US; + public boolean Online; + public boolean Alive; +} diff --git a/Plugins[Modified]/Mineplex.StaffServer/dependency-reduced-pom.xml b/Plugins[Modified]/Mineplex.StaffServer/dependency-reduced-pom.xml deleted file mode 100644 index b439f4a1..00000000 --- a/Plugins[Modified]/Mineplex.StaffServer/dependency-reduced-pom.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - mineplex-plugin - com.mineplex - dev-SNAPSHOT - ../plugin.xml - - 4.0.0 - mineplex-staffserver - StaffServer - - diff --git a/Plugins[Modified]/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java b/Plugins[Modified]/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java index 33774d03..ac90c08b 100644 --- a/Plugins[Modified]/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java +++ b/Plugins[Modified]/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java @@ -1,22 +1,43 @@ 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.account.CoreClientManager; -import mineplex.core.account.command.RanksCommand; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.bonuses.BonusRepository; import mineplex.core.command.CommandCenter; import mineplex.core.common.Constants; +import mineplex.core.creature.Creature; import mineplex.core.disguise.DisguiseManager; +import mineplex.core.donation.DonationManager; import mineplex.core.elo.EloManager; import mineplex.core.inventory.InventoryManager; 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; +import mineplex.core.profileCache.ProfileCacheManager; +import mineplex.core.punish.Punish; import mineplex.core.recharge.Recharge; import mineplex.core.stats.StatsManager; +import mineplex.core.status.ServerStatusManager; +import mineplex.core.updater.FileUpdater; import mineplex.core.updater.Updater; -import net.minecraft.server.v1_8_R3.MinecraftServer; -import org.bukkit.Bukkit; -import org.bukkit.plugin.java.JavaPlugin; -import org.spigotmc.SpigotConfig; +import mineplex.staffServer.customerSupport.CustomerSupport; +import mineplex.staffServer.salespackage.SalesPackageManager; import static mineplex.core.Managers.require; @@ -34,31 +55,58 @@ public class StaffServer extends JavaPlugin CoreClientManager clientManager = new CoreClientManager(this); CommandCenter.Instance.setClientManager(clientManager); Recharge.Initialize(this); - - clientManager.addCommand(new RanksCommand(clientManager)); - - //Punish punish = new Punish(this, clientManager); - //new NpcManager(this, new Creature(this)); - //ServerStatusManager serverStatusManager = new ServerStatusManager(this, clientManager, new LagMeter(this, clientManager)); - //PreferencesManager preferenceManager = new PreferencesManager(this, null, clientManager); + + DonationManager donationManager = require(DonationManager.class); + + Punish punish = new Punish(this, clientManager); + new NpcManager(this, new Creature(this)); + ServerStatusManager serverStatusManager = new ServerStatusManager(this, clientManager, new LagMeter(this, clientManager)); + PreferencesManager preferenceManager = new PreferencesManager(this, null, clientManager); Portal portal = new Portal(); EloManager eloManager = new EloManager(this, clientManager); StatsManager statsManager = new StatsManager(this, clientManager); InventoryManager inventoryManager = new InventoryManager(this, clientManager); - new MemoryFix(this); - //new FileUpdater(GenericServer.HUB); + BonusRepository bonusRepository = new BonusRepository(this, null, donationManager); + new AchievementManager(statsManager, clientManager, donationManager, null, eloManager); + new MemoryFix(this); + new FileUpdater(GenericServer.HUB); require(PacketHandler.class); require(DisguiseManager.class); + PowerPlayClubRepository powerPlayRepo = new PowerPlayClubRepository(this, clientManager, donationManager); + + SalesPackageManager salesPackageManager = new SalesPackageManager(this, clientManager, donationManager, inventoryManager, statsManager, powerPlayRepo); + + new CustomerSupport(this, clientManager, donationManager, powerPlayRepo, inventoryManager, bonusRepository); + + //Updates require(Updater.class); MinecraftServer.getServer().getPropertyManager().setProperty("debug", false); SpigotConfig.debug = false; Bukkit.getWorlds().get(0).setSpawnLocation(0, 102, 0); + + ((CraftServer)getServer()).setWhitelist(true); + + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("377bdea3-badc-448d-81c1-65db43b17ea4"), "Strutt20")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("cf1b629c-cc55-4eb4-be9e-3ca86dfc7b9d"), "mannalou")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("492ff708-fe76-4c5a-b9ed-a747b5fa20a0"), "cherdy")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("6edf17d5-6bb2-4ed9-92e9-bed8e96fff68"), "BlueBeetleHD")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("a47a4d04-9f51-44ba-9d35-8de6053e9289"), "AlexTheCoder")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("63ad2db3-7c62-4a10-ac58-d267973190ce"), "Crumplex")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("a20d59d1-cfd8-4116-ac27-45d9c7eb4a97"), "Artix")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("852a8acf-7337-40d7-99ec-b08fd99650b5"), "KingCrazy_")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("d514022f-f6e3-4fb0-8d8c-90a6c2802711"), "sjsampson")); + ((CraftServer)getServer()).getHandle().addWhitelist(new GameProfile(UUID.fromString("627070a4-c6e0-46a4-a6b8-97f440dc37b4"), "Toki")); - //require(ProfileCacheManager.class); + ((CraftServer)getServer()).getHandle().addOp(new GameProfile(UUID.fromString("a47a4d04-9f51-44ba-9d35-8de6053e9289"), "AlexTheCoder")); + ((CraftServer)getServer()).getHandle().addOp(new GameProfile(UUID.fromString("cf1b629c-cc55-4eb4-be9e-3ca86dfc7b9d"), "mannalou")); + ((CraftServer)getServer()).getHandle().addOp(new GameProfile(UUID.fromString("377bdea3-badc-448d-81c1-65db43b17ea4"), "Strutt20")); + ((CraftServer)getServer()).getHandle().addOp(new GameProfile(UUID.fromString("6edf17d5-6bb2-4ed9-92e9-bed8e96fff68"), "BlueBeetleHD")); + + require(ProfileCacheManager.class); } } diff --git a/Plugins[Modified]/Mineplex.StaffServer/target/classes/plugin.yml b/Plugins[Modified]/Mineplex.StaffServer/target/classes/plugin.yml new file mode 100644 index 00000000..24ee14bd --- /dev/null +++ b/Plugins[Modified]/Mineplex.StaffServer/target/classes/plugin.yml @@ -0,0 +1,3 @@ +name: StaffServer +main: mineplex.staffServer.StaffServer +version: 0.1 \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Votifier/plugin.yml b/Plugins[Modified]/Mineplex.Votifier/plugin.yml new file mode 100644 index 00000000..75a40f89 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Votifier/plugin.yml @@ -0,0 +1,3 @@ +name: MineplexVotifier +main: mineplex.votifier.Votifier +version: 0.1 \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Votifier/pom.xml b/Plugins[Modified]/Mineplex.Votifier/pom.xml new file mode 100644 index 00000000..23f4e3d0 --- /dev/null +++ b/Plugins[Modified]/Mineplex.Votifier/pom.xml @@ -0,0 +1,26 @@ + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + MineplexVotifier + mineplex-votifier + + + + ${project.groupId} + mineplex-core + ${project.version} + + + com.vexsoftware + votifier + + + \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Votifier/src/mineplex/votifier/Votifier.java b/Plugins[Modified]/Mineplex.Votifier/src/mineplex/votifier/Votifier.java new file mode 100644 index 00000000..50ef4dad --- /dev/null +++ b/Plugins[Modified]/Mineplex.Votifier/src/mineplex/votifier/Votifier.java @@ -0,0 +1,35 @@ +package mineplex.votifier; + +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.command.CommandCenter; +import mineplex.core.donation.DonationManager; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.stats.StatsManager; + +public class Votifier extends JavaPlugin +{ + private String WEB_CONFIG = "webServer"; + + @Override + public void onEnable() + { + getConfig().addDefault(WEB_CONFIG, "http://accounts.mineplex.com/"); + getConfig().set(WEB_CONFIG, getConfig().getString(WEB_CONFIG)); + saveConfig(); + + String webServerAddress = getConfig().getString(WEB_CONFIG); + + CommandCenter.Initialize(this); + CoreClientManager clientManager = new CoreClientManager(this); + DonationManager donationManager = Managers.require(DonationManager.class); + BonusManager bonusManager = new BonusManager(this, clientManager, donationManager); + InventoryManager inventoryManager = new InventoryManager(this, clientManager); + StatsManager statsManager = new StatsManager(this, clientManager); + + VotifierManager vote = new VotifierManager(this, clientManager, donationManager, bonusManager, inventoryManager, statsManager); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins[Modified]/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java new file mode 100644 index 00000000..063a367b --- /dev/null +++ b/Plugins[Modified]/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -0,0 +1,408 @@ +package mineplex.votifier; + +import java.io.File; +import java.io.IOException; +import java.sql.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; +import org.jooq.DSLContext; +import org.jooq.Record1; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; + +import com.vexsoftware.votifier.model.Vote; +import com.vexsoftware.votifier.model.VotifierEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.redis.VotifierCommand; +import mineplex.core.common.Pair; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.donation.DonationManager; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.stats.StatsManager; +import mineplex.core.treasure.types.TreasureType; +import mineplex.database.Tables; +import mineplex.database.tables.records.BonusRecord; +import mineplex.serverdata.Region; +import mineplex.serverdata.Utility; +import mineplex.serverdata.commands.ServerCommand; +import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.redis.RedisConfig; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +public class VotifierManager extends MiniPlugin +{ + private CoreClientManager _clientManager; + private DonationManager _donationManager; + private BonusManager _bonusManager; + private InventoryManager _inventoryManager; + private StatsManager _statsManager; + + private RedisConfig _usConfig; + private RedisConfig _euConfig; + private RedisDataRepository _usPlayerRepo; + private RedisDataRepository _euPlayerRepo; + private JedisPool _usWritePool; + private JedisPool _euWritePool; + + private final boolean ClansVotifier; + + public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, BonusManager bonusManager, InventoryManager inventoryManager, StatsManager statsManager) + { + super("Votifier", plugin); + + _clientManager = clientManager; + _donationManager = donationManager; + _bonusManager = bonusManager; + _inventoryManager = inventoryManager; + _statsManager = statsManager; + + _usConfig = ServerManager.loadConfig("us-redis.dat"); + _euConfig = ServerManager.loadConfig("eu-redis.dat"); + + _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), + _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), + _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); + + _usWritePool = Utility.generatePool(_usConfig.getConnection(true, "DefaultConnection")); + _euWritePool = Utility.generatePool(_euConfig.getConnection(true, "DefaultConnection")); + + boolean found = false; + try + { + found = new File(new File(".").getCanonicalPath() + File.separator + "ClansVotifier.dat").exists(); + } + catch (IOException e) + { + e.printStackTrace(); + } + ClansVotifier = found; + } + + @EventHandler + public void handleVote(VotifierEvent event) + { + final Vote vote = event.getVote(); + final String playerName = vote.getUsername(); + + System.out.println("New Vote: " + playerName); + + runAsync(new Runnable() + { + @Override + public void run() + { + UUID uuid = UUIDFetcher.getUUIDOf(playerName); + if (uuid == null) + { + System.out.println("Failed to load UUID of " + playerName + " from UUIDFetcher. Trying with database"); + uuid = _clientManager.loadUUIDFromDB(playerName); + + if (uuid == null) + { + System.out.println("Failed to load UUID from database. Giving up on " + playerName); + } + } + + final PlayerStatus usStatus = _usPlayerRepo.getElement(uuid.toString()); + final PlayerStatus euStatus = _euPlayerRepo.getElement(uuid.toString()); + + System.out.println("Loaded " + playerName + " with uuid " + uuid); + System.out.println("Attempting to award bonus"); + final UUID finalUuid = uuid; + awardBonus(playerName, finalUuid, new Callback() + { + @Override + public void run(final Integer reward) + { + runSync(new Runnable() + { + @Override + public void run() + { + if (usStatus != null) + { + System.out.println("Found " + playerName + " on US " + usStatus.getServer()); + notifyServer(playerName, reward, Region.US, usStatus.getServer()); + } + + if (euStatus != null) + { + System.out.println("Found " + playerName + " on EU " + euStatus.getServer()); + notifyServer(playerName, reward, Region.EU, euStatus.getServer()); + } + } + }); + } + }); + } + }); + System.out.println(); + System.out.println(); + +// UUID uuid = _clientManager.loadUUIDFromDB(playerName); +// if (uuid != null) +// { +// System.out.println("Found UUID:" + uuid.toString()); +// if (playerName.equalsIgnoreCase("Phinary")) +// { +// System.out.println("award bonus"); +// awardBonus(uuid); +// } +// } +// else +// { +// System.out.println("Failed to load UUID for player: " + playerName); +// } + +// PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); +// if (usStatus != null) +// { +// System.out.println("Found on US Server: " + usStatus.getServer()); +// writePool = _usWritePool; +// serverName = usStatus.getServer(); +// } +// +// PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); +// if (euStatus != null) +// { +// System.out.println("Found on EU Server: " + euStatus.getServer()); +// writePool = _euWritePool; +// serverName = euStatus.getServer(); +// } + + // Currently we just notify all servers, and the server with the player on it can deal with it +// notifyServer(playerName, true); + } + + private void notifyServer(String playerName, int reward, Region region, String targetServer) + { + JedisPool writePool = region == Region.EU ? _euWritePool : _usWritePool; + + VotifierCommand command = new VotifierCommand(playerName, reward, ClansVotifier, targetServer); + publishCommand(command, writePool); + } + + private void awardBonus(final String playerName, final UUID uuid, final Callback onComplete) + { + DSLContext create = DSL.using(DBPool.getAccount(), SQLDialect.MYSQL); + + Record1 idRecord = create.select(Tables.accounts.id).from(Tables.accounts).where(Tables.accounts.uuid.eq(uuid.toString())).fetchOne(); + if (idRecord != null) + { + final int accountId = idRecord.value1(); + final BonusRecord client = _bonusManager.getRepository().loadRecord(playerName, accountId); + final int homeServerId = _bonusManager.getRepository().loadClansServerId(accountId); + if (homeServerId == -1 && ClansVotifier) + { + return; + } + final BonusAmount amount = ClansVotifier ? _bonusManager.getClansVoteBonusAmount(homeServerId) : _bonusManager.getVoteBonusAmount(client.getVoteStreak()); + + _bonusManager.getRepository().attemptVoteBonus(accountId, ClansVotifier, new Callback>() + { + @Override + public void run(Pair pair) + { + if (pair.getLeft()) + { + // Reward Amount + final int gems = amount.getTotalGems(); + final int gold = amount.getTotalGold(); + final int shards = amount.getTotalShards(); + final int tickets = amount.getTickets(); + int experience = amount.getTotalExperience(); + int oldChests = amount.getOldChests(); + int ancientChests = amount.getAncientChests(); + int mythicalChests = amount.getMythicalChests(); + int illuminatedChests = amount.getIlluminatedChests(); + int omegaChests = amount.getOmegaChests(); + + if (oldChests > 0) + { + _inventoryManager.addItemToInventoryForOffline(data -> + { + if (data) + { + System.out.println("Gave " + oldChests + " old chest(s) to " + playerName); + } + else + { + System.out.println("Failed to give " + oldChests + " old chest(s) to " + playerName); + } + }, accountId, TreasureType.OLD.getItemName(), oldChests); + } + +// if (ancientChests > 0) +// { +// _inventoryManager.addItemToInventoryForOffline(data -> +// { +// if (data) +// { +// System.out.println("Gave " + ancientChests + " ancient chest(s) to " + playerName); +// } +// else +// { +// System.out.println("Failed to give " + ancientChests + " ancient chest(s) to " + playerName); +// } +// }, accountId, TreasureType.ANCIENT.getItemName(), ancientChests); +// } +// +// if (mythicalChests > 0) +// { +// _inventoryManager.addItemToInventoryForOffline(data -> +// { +// if (data) +// { +// System.out.println("Gave " + mythicalChests + " mythical chest(s) to " + playerName); +// } +// else +// { +// System.out.println("Failed to give " + mythicalChests + " mythical chest(s) to " + playerName); +// } +// }, accountId, TreasureType.MYTHICAL.getItemName(), mythicalChests); +// } +// +// if (illuminatedChests > 0) +// { +// _inventoryManager.addItemToInventoryForOffline(data -> +// { +// if (data) +// { +// System.out.println("Gave " + illuminatedChests + " illuminated chest(s) to " + playerName); +// } +// else +// { +// System.out.println("Failed to give " + illuminatedChests + " illuminated chest(s) to " + playerName); +// } +// }, accountId, TreasureType.ILLUMINATED.getItemName(), illuminatedChests); +// } +// +// if (omegaChests > 0) +// { +// _inventoryManager.addItemToInventoryForOffline(data -> +// { +// if (data) +// { +// System.out.println("Gave " + omegaChests + " omega chest(s) to " + playerName); +// } +// else +// { +// System.out.println("Failed to give " + omegaChests + " omega chest(s) to " + playerName); +// } +// }, accountId, TreasureType.OMEGA.getItemName(), omegaChests); +// } + + if (gems > 0) + { + _donationManager.rewardCurrency(GlobalCurrency.GEM, playerName, uuid, "Votifier", gems, data -> + { + if (data) + { + System.out.println("Gave " + gems + " gems to " + playerName); + } + else + { + System.out.println("Failed to give " + gems + " gems to " + playerName); + } + }); + } + + if (gold > 0) + { + Set serverIds = new HashSet<>(); + serverIds.addAll(amount.getGold().getServerIds()); + serverIds.addAll(amount.getBonusGold().getServerIds()); + for (Integer serverId : serverIds) + { + int goldCount = amount.getGold().getGoldFor(serverId) + amount.getBonusGold().getGoldFor(serverId); + _donationManager.getGoldRepository().rewardGold(data -> + { + if (data) + { + System.out.println("Gave " + goldCount + " gold to " + playerName + " on clans server id " + serverId); + } + else + { + System.out.println("Failed to give " + goldCount + " gold to " + playerName + " on clans server id " + serverId); + } + }, serverId, accountId, goldCount); + } + } + + if (shards > 0) + { + _donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, playerName, uuid, "Votifier", shards, data -> + { + if (data) + { + System.out.println("Gave " + shards + " shards to " + playerName); + } + else + { + System.out.println("Failed to give " + shards + " shards to " + playerName); + } + }); + } + + if (experience > 0) + { + _statsManager.incrementStat(accountId, "Global.ExpEarned", experience); + System.out.println("Gave " + experience + " experience to " + playerName); + } + + if (tickets > 0) + { + client.setTickets(client.getTickets() + tickets); + } + + // Check if we need to reset vote streak + _bonusManager.updateVoteStreak(client); + client.setVotetime(pair.getRight()); + + // Update Streak + _bonusManager.incrementVoteStreak(client); + + client.store(); + System.out.println("Awarded " + tickets + " carl ticket(s) to " + playerName); + onComplete.run(ClansVotifier ? amount.getTotalGold() : amount.getTotalGems()); + } + else + { + System.out.println(playerName + " attempted to vote, vote bonus returned false!"); + } + } + }); + } + } + + private void publishCommand(final ServerCommand serverCommand, final JedisPool writePool) + { + new Thread(new Runnable() + { + public void run() + { + try (Jedis jedis = writePool.getResource()) + { + String commandType = serverCommand.getClass().getSimpleName(); + String serializedCommand = Utility.serialize(serverCommand); + jedis.publish("commands.server" + ":" + commandType, serializedCommand); + } + } + }).start(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/plugin.yml b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/plugin.yml new file mode 100644 index 00000000..66259a49 --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/plugin.yml @@ -0,0 +1,3 @@ +name: UHC-WorldGen +main: nautilus.game.arcade.uhc.WorldGen +version: 0.1 \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml new file mode 100644 index 00000000..7274ce32 --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml @@ -0,0 +1,45 @@ + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + + + + com.mineplex + file://${project.basedir}/../lib + + + + UHC WorldGen + nautilus-game-arcade-uhc-worldgen + + + + com.mineplex + spigot + 1.0 + compile + + + org.zeroturnaround + zt-zip + 1.9 + + + diff --git a/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java new file mode 100644 index 00000000..24d2483e --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java @@ -0,0 +1,336 @@ +package nautilus.game.arcade.uhc; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +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 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 +{ + // 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 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().getPluginManager().registerEvents(this, this); + + File root = new File("."); + + if (!root.exists()) + { + getLogger().severe("Root folder does not exist. Aborting"); + System.exit(0); + return; + } + + File outputDirectory = new File(root, "output"); + if (!outputDirectory.exists()) + { + if (!outputDirectory.mkdir()) + { + getLogger().severe("Could not create output folder. Aborting"); + System.exit(0); + return; + } + } + + long seed = ThreadLocalRandom.current().nextLong(); + + File outputFile = new File(outputDirectory, "UHC_Map" + seed + ".zip"); + + if (outputFile.exists()) + { + getLogger().info("Seed " + seed + " has already been generated. Skipping"); + System.exit(0); + return; + } + + try + { + if (!outputFile.createNewFile()) + { + getLogger().severe("Could not create new output file. Aborting"); + System.exit(0); + return; + } + } + catch (IOException e) + { + getLogger().log(Level.SEVERE, "Could not create new output file. Aborting", e); + 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.setKeepSpawnInMemory(false); + world.setDifficulty(Difficulty.HARD); + WorldBorder border = world.getWorldBorder(); + border.setCenter(0.0, 0.0); + border.setSize(MAP_SIZE * 2); + + 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 treeSet = ((HashTreeSet) mfield.get(nmsWorld)); + + for (int x = minChunkX; x <= maxChunkX; x++) + { + getLogger().info("Generating x coord " + x); + 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++) + { + getLogger().info("Unloading x coord " + x); + for (int z = minChunkZ; z <= maxChunkZ; z++) + { + 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"); + + Bukkit.unloadWorld(world, true); + + getLogger().info("Finished unloading and saving world"); + + 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(-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()); + worldconfig.append("TEAM_SPAWNS:0,0,0").append(System.lineSeparator()); + } + + File worldFolder = new File(root, "generating"); + + File regionFolder = new File(worldFolder, "region"); + + File[] regionFiles = regionFolder.listFiles(); + + if (regionFiles == null) + { + getLogger().severe("Unexpected null region files. Aborting"); + System.exit(0); + return; + } + + List zipEntrySourceList = new ArrayList<>(); + zipEntrySourceList.add(new ByteSource("WorldConfig.dat", worldconfig.toString().getBytes(StandardCharsets.UTF_8))); + for (File file : regionFiles) + { + zipEntrySourceList.add(new FileSource("region/" + file.getName(), file)); + } + 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(); + } +} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/target/classes/plugin.yml b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/target/classes/plugin.yml new file mode 100644 index 00000000..66259a49 --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade.UHC.WorldGen/target/classes/plugin.yml @@ -0,0 +1,3 @@ +name: UHC-WorldGen +main: nautilus.game.arcade.uhc.WorldGen +version: 0.1 \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/dependency-reduced-pom.xml b/Plugins[Modified]/Nautilus.Game.Arcade/dependency-reduced-pom.xml deleted file mode 100644 index f5726359..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/dependency-reduced-pom.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - mineplex-plugin - com.mineplex - dev-SNAPSHOT - ../plugin.xml - - 4.0.0 - nautilus-game-arcade - Arcade - - diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/DebugCommand.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/DebugCommand.java deleted file mode 100644 index dcc19814..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/DebugCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package nautilus.game.arcade.game; - -import org.bukkit.entity.Player; - -import mineplex.core.Managers; -import mineplex.core.account.permissions.Permission; -import mineplex.core.command.CommandBase; -import nautilus.game.arcade.ArcadeManager; - -public class DebugCommand extends CommandBase -{ - private final DebugCommandExecutor _executor; - - public DebugCommand(String commandName, Permission permission, DebugCommandExecutor executor) - { - super(Managers.get(ArcadeManager.class), permission, commandName); - - _executor = executor; - } - - public void Execute(Player caller, String[] args) - { - _executor.execute(caller, args); - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/DebugCommandExecutor.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/DebugCommandExecutor.java deleted file mode 100644 index cdc31488..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/DebugCommandExecutor.java +++ /dev/null @@ -1,9 +0,0 @@ -package nautilus.game.arcade.game; - -import org.bukkit.entity.Player; - -@FunctionalInterface -public interface DebugCommandExecutor -{ - void execute(Player player, String[] args); -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/Game.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/Game.java deleted file mode 100644 index 2a5b0db4..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/Game.java +++ /dev/null @@ -1,2205 +0,0 @@ -package nautilus.game.arcade.game; - -import com.mojang.authlib.GameProfile; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.arcadeevents.CoreGameStartEvent; -import mineplex.core.arcadeevents.CoreGameStopEvent; -import mineplex.core.command.CommandCenter; -import mineplex.core.common.util.*; -import mineplex.core.disguise.disguises.DisguisePlayer; -import mineplex.core.elo.EloPlayer; -import mineplex.core.elo.EloTeam; -import mineplex.core.game.MineplexGameManager; -import mineplex.core.game.kit.KitAvailability; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.lifetimes.Lifetimed; -import mineplex.core.lifetimes.ListenerComponent; -import mineplex.core.lifetimes.PhasedLifetime; -import mineplex.core.mission.MissionTracker; -import mineplex.core.packethandler.IPacketHandler; -import mineplex.core.preferences.Preference; -import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.core.utils.UtilGameProfile; -import mineplex.minecraft.game.classcombat.event.ClassCombatCreatureAllowSpawnEvent; -import mineplex.minecraft.game.core.combat.DeathMessageType; -import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; -import nautilus.game.arcade.ArcadeFormat; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.events.PlayerGameRespawnEvent; -import nautilus.game.arcade.events.PlayerPrepareTeleportEvent; -import nautilus.game.arcade.events.PlayerStateChangeEvent; -import nautilus.game.arcade.game.GameTeam.PlayerState; -import nautilus.game.arcade.game.modules.AntiExpOrbModule; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryModule; -import nautilus.game.arcade.game.team.GameTeamModule; -import nautilus.game.arcade.game.team.selectors.EvenTeamSelector; -import nautilus.game.arcade.game.team.selectors.TeamSelector; -import nautilus.game.arcade.kit.ChampionsKit; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.kit.LinearUpgradeKit; -import nautilus.game.arcade.kit.Perk; -import nautilus.game.arcade.managers.GamePlayerManager; -import nautilus.game.arcade.managers.chat.ChatStatData; -import nautilus.game.arcade.managers.lobby.LobbyManager; -import nautilus.game.arcade.missions.*; -import nautilus.game.arcade.scoreboard.GameScoreboard; -import nautilus.game.arcade.stats.*; -import nautilus.game.arcade.wineffect.WinEffectManager; -import nautilus.game.arcade.world.WorldData; -import net.minecraft.server.v1_8_R3.EntityItem; -import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; -import org.apache.commons.lang3.tuple.Triple; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Hanging; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.entity.ItemSpawnEvent; -import org.bukkit.event.hanging.HangingBreakEvent; -import org.bukkit.event.hanging.HangingPlaceEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.world.WorldLoadEvent; -import org.bukkit.scoreboard.NameTagVisibility; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; -import org.bukkit.util.Vector; - -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -//import mineplex.core.antihack.AntiHack; - -public abstract class Game extends ListenerComponent implements Lifetimed -{ - private final static int MAX_TICK_SPEED_MEASUREMENT = 40; - - public long getGameLiveTime() - { - return _gameLiveTime; - } - - public void setGameLiveTime(long gameLiveTime) - { - _gameLiveTime = gameLiveTime; - } - - public enum GameState - { - PreLoad, Loading, Recruit, Prepare, Live, End, Dead - } - - public ArcadeManager Manager; - - // Game - private GameType _gameType; - protected String[] _gameDesc; - - private PhasedLifetime _lifetime = new PhasedLifetime<>(); - - // State - private GameState _gameState = GameState.PreLoad; - private long _gameLiveTime; - private long _gameStateTime = System.currentTimeMillis(); - - private boolean _prepareCountdown = false; - - private int _countdown = -1; - private boolean _countdownForce = false; - - private String _customWinLine = ""; - private NautHashMap _customWinMessages = new NautHashMap(); - - // Kits - private Kit[] _kits; - - // Teams - private final GameTeamModule _teamModule; - protected ArrayList _teamList = new ArrayList(); - protected TeamSelector _teamSelector = new EvenTeamSelector(); - public boolean TeamMode = false; - - // Player Preferences - protected NautHashMap _playerKit = new NautHashMap(); - - // Player Data - private NautHashMap> _gemCount = new NautHashMap>(); - private final Map> _stats = new HashMap<>(); - private NautHashMap _playerInTime = new NautHashMap<>(); - - // Player Location Store - private final Map _playerLocationStore = new HashMap<>(); - - // Scoreboard - protected GameScoreboard Scoreboard; - public boolean UseCustomScoreboard = false; - - // Loaded from Map Config - public WorldData WorldData; - - // Game Help - private int _helpIndex = 0; - private ChatColor _helpColor; - protected String[] _help; - - // Gameplay Flags - public long GameTimeout = 1200000; - - public boolean SpectatorAllowed = true; - - public boolean Damage = true; - public boolean DamagePvP = true; - public boolean DamagePvE = true; - public boolean DamageEvP = true; - public boolean DamageSelf = true; - public boolean DamageFall = true; - public boolean DamageTeamSelf = false; - public boolean DamageTeamOther = true; - - public boolean BlockBreak = false; - public boolean BlockBreakCreative = false; - public HashSet BlockBreakAllow = new HashSet(); - public HashSet BlockBreakDeny = new HashSet(); - - public boolean BlockPlace = false; - public boolean BlockPlaceCreative = false; - public HashSet BlockPlaceAllow = new HashSet(); - public HashSet BlockPlaceDeny = new HashSet(); - - public boolean ItemPickup = false; - public HashSet ItemPickupAllow = new HashSet(); - public HashSet ItemPickupDeny = new HashSet(); - - public boolean ItemDrop = false; - public HashSet ItemDropAllow = new HashSet(); - public HashSet ItemDropDeny = new HashSet(); - - public boolean InventoryOpenBlock = false; - public boolean InventoryOpenChest = false; - public boolean InventoryClick = false; - - public boolean PrivateBlocks = false; - - public boolean DeathOut = true; - public boolean DeathDropItems = false; - public boolean DeathMessages = true; - - public double DeathSpectateSecs = 0; - public boolean DeathTeleport = true; - - public boolean QuitOut = true; - public boolean QuitDropItems = false; - - public boolean CreatureAllow = false; - public boolean CreatureAllowOverride = false; - - public int WorldTimeSet = 12000; - public boolean WorldWeatherEnabled = false; - public int WorldWaterDamage = 0; - public boolean WorldBoundary = true; - public boolean WorldBoundaryKill = true; - public boolean WorldBlockBurn = false; - public boolean WorldBlockGrow = false; - public boolean WorldFireSpread = false; - public boolean WorldLeavesDecay = false; - public boolean WorldSoilTrample = false; - public boolean WorldBoneMeal = false; - public boolean WorldChunkUnload = false; - - public boolean AllowFlintAndSteel = false; - - public int HungerSet = -1; - public int HealthSet = -1; - - public boolean SpawnTeleport = true; - - private double _itemMergeRadius = 0; - - public boolean AnnounceStay = true; - public boolean AnnounceJoinQuit = true; - public boolean AnnounceSilence = true; - - public GameState KitRegisterState = GameState.Live; - - public boolean JoinInProgress = false; - - public int TickPerTeleport = 1; - - public boolean SpawnNearAllies = false; - public boolean SpawnNearEnemies = false; - - public boolean StrictAntiHack = false; - public boolean AnticheatDisabled = false; - - public boolean DisableKillCommand = true; - - public boolean GadgetsDisabled = true; - - public boolean TeleportsDisqualify = true; - - public GameMode PlayerGameMode = GameMode.SURVIVAL; - - // Addons - public boolean SoupEnabled = true; - - public boolean GiveClock = true; - - public boolean AllowParticles = true; - public boolean ShowWeaponNames = true; - - public boolean Prepare = true; - public long PrepareTime = 9000; - public boolean PrepareFreeze = true; - public boolean PrepareAutoAnnounce = true; - public boolean PlaySoundGameStart = true; - - public double XpMult = 1; - - public boolean SpeedMeasurement = false; - - // Chat Stats - public final ChatStatData Kills = new ChatStatData("Kills", "Kills", true); - public final ChatStatData Assists = new ChatStatData("Assists", "Assists", true); - public final ChatStatData DamageDealt = new ChatStatData("Damage Dealt", "Damage Dealt", true); - public final ChatStatData DamageTaken = new ChatStatData("Damage Taken", "Damage Taken", true); - public final ChatStatData DamageTakenPVP = new ChatStatData("Damage Taken PvP", "Damage Taken", true); - public final ChatStatData Deaths = new ChatStatData("Deaths", "Deaths", true); - public final ChatStatData ExpEarned = new ChatStatData("ExpEarned", "Exp Earned", true); - public final ChatStatData GamesPlayed = new ChatStatData("GamesPlayed", "Games Played", true); - public final ChatStatData GemsEarned = new ChatStatData("GemsEarned", "Gems Earned", true); - public final ChatStatData Losses = new ChatStatData("Losses", "Losses", true); - public final ChatStatData Wins = new ChatStatData("Wins", "Wins", true); - public final ChatStatData KDRatio = new ChatStatData("KDRatio", "KD-Ratio", true); - public final ChatStatData BlankLine = new ChatStatData().blankLine(); - - // Gems - public boolean CrownsEnabled = false; - - public double GemMultiplier = 1; - public boolean GemHunterEnabled = true; - public boolean GemBoosterEnabled = true; - public boolean GemDoubleEnabled = true; - - public double GemKillDeathRespawn = .5; - public double GemAssistDeathRespawn = .5; - - public double GemKillDeathOut = 4; - public double GemAssistDeathOut = 1; - - // Gameplay Data - public HashMap PrivateBlockMap = new HashMap(); - public HashMap PrivateBlockCount = new HashMap(); - - public Location SpectatorSpawn = null; - - public boolean FirstKill = true; - public int FirstKillReward = 10; - - public String Winner = "Nobody"; - public GameTeam WinnerTeam = null; - - //ELO - public boolean EloRanking = false; - public int EloStart = 1000; - - public boolean CanAddStats = true; - public boolean CanGiveLoot = true; - - public boolean HideTeamSheep = false; - public boolean ReplaceTeamsWithKits = false; - - public boolean DeadBodies = false; - public boolean DeadBodiesQuit = true; - public boolean DeadBodiesDeath = true; - public int DeadBodiesExpire = -1; - - public boolean EnableTutorials = false; - - public boolean FixSpawnFacing = true; - - public boolean AllowEntitySpectate = true; - - // Used for "%player% is your teammate" - public boolean ShowTeammateMessage = false; - - public boolean ShowEveryoneSpecChat = true; - - // Split Kit XP - public boolean SplitKitXP = false; - - public boolean NightVision = false; - - private IPacketHandler _useEntityPacketHandler; - private int _deadBodyCount; - private NautHashMap _deadBodies = new NautHashMap(); - private NautHashMap _deadBodiesExpire = new NautHashMap(); - - private final Set> _statTrackers = new HashSet<>(); - - public final WinEffectManager WinEffectManager = new WinEffectManager(); - public boolean WinEffectEnabled = true; - - private Map, Module> _modules = new HashMap<>(); - - private HashMap>> _playerPastLocs = new HashMap<>(); - private Set _debugCommands = new HashSet<>(); - - public enum Perm implements Permission - { - DEBUG_COMMANDS - } - - public Game(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc) - { - Manager = manager; - - _lifetime.register(this); - - // Game - _gameType = gameType; - _gameDesc = gameDesc; - - // Kits - _kits = kits; - - // Scoreboard - Scoreboard = new GameScoreboard(this); - WorldData = new WorldData(this); - - // Stat Trackers - registerStatTrackers( - new KillsStatTracker(this), - new DeathsStatTracker(this), - new AssistsStatTracker(this), - new ExperienceStatTracker(this), - new WinStatTracker(this), - new LoseStatTracker(this), - new DamageDealtStatTracker(this), - new DamageTakenStatTracker(this), - new GamesPlayedStatTracker(this) - ); - - // Mission Tracks - registerMissions( - new PlayGameMissionTracker(this), - new WinMissionTracker(this), - new KillMissionTracker(this), - new DamageMissionTracker(this), - new CraftItemMissionTracker(this), - new EnchantItemMissionTracker(this), - new WalkMissionTracker(this), - new BlocksMissionTracker(this), - new FurnaceMissionTracker(this) - ); - manager.getMissionsManager().setCanIncrement(() -> CanAddStats && (InProgress() || GetState() == GameState.End) && manager.IsRewardStats()); - - Manager.getResourcePackManager().setResourcePack(gameType.getResourcePackUrls(this), gameType.isEnforceResourcePack(this)); - - _useEntityPacketHandler = packetInfo -> - { - if (packetInfo.getPacket() instanceof PacketPlayInUseEntity) - { - net.minecraft.server.v1_8_R3.Entity entity = ((PacketPlayInUseEntity) packetInfo.getPacket()) - .a(((CraftWorld) packetInfo.getPlayer().getWorld()).getHandle()); - - if (entity instanceof EntityItem) - { - packetInfo.setCancelled(true); - } - } - }; - - System.out.println("Loading " + GetName() + "..."); - - new AntiExpOrbModule().register(this); - new GameSummaryModule() - .register(this); - _teamModule = new GameTeamModule(); - _teamModule.register(this); - - registerDebugCommand("kit", Perm.DEBUG_COMMANDS, PermissionGroup.ADMIN, (caller, args) -> - { - String kit = Arrays.stream(args).collect(Collectors.joining(" ")); - - for (Kit gkit : GetKits()) - { - if (kit.equalsIgnoreCase(gkit.GetName())) - { - SetKit(caller, gkit, true); - return; - } - } - - caller.sendMessage(F.main("Kit", "Sorry, but that is not a kit!")); - }); - registerDebugCommand("cooldown", Perm.DEBUG_COMMANDS, PermissionGroup.ADMIN, (caller, args) -> - { - for (Player other : UtilServer.getPlayers()) - { - Recharge.Instance.Reset(other); - } - - Announce(C.cWhiteB + caller.getName() + C.cAquaB + " reset cooldowns!"); - }); - } - - // You should never use this so please don't. Use Module.register instead - public final void registerModule(Module module) - { - if (!_modules.containsKey(module.getClass())) - { - _modules.put(module.getClass(), module); - UtilServer.RegisterEvents(module); - module.initialize(this); - } - else - { - throw new IllegalStateException("Module " + module.getClass() + " is already registered"); - } - } - - public void unregisterModule(Module module) - { - if (_modules.containsKey(module.getClass()) && _modules.get(module.getClass()) == module) - { - _modules.remove(module.getClass()); - module.cleanup(); - HandlerList.unregisterAll(module); - } - } - - public & Permission> void registerDebugCommand(String commandName, T permission, PermissionGroup defaultRank, DebugCommandExecutor executor) - { - DebugCommand command = new DebugCommand(commandName, permission, executor); - if (defaultRank != null) - { - defaultRank.setPermission(permission, true, true); - } - if (UtilServer.isTestServer()) - { - PermissionGroup.QA.setPermission(permission, true, true); - } - _debugCommands.add(command); - for (String string : command.Aliases()) - { - if (CommandCenter.getCommands().containsKey(string.toLowerCase())) - { - throw new IllegalArgumentException("Existing command: " + string.toLowerCase()); - } - } - CommandCenter.Instance.addCommand(command); - } - - public void setKits(Kit[] kits) - { - _kits = kits; - } - - public String GetName() - { - return _gameType.getName(); - } - - public static GameType[] getWorldHostNames(GameType targetType) - { - GameType[] mapSource = new GameType[] - { - targetType - }; - - if (targetType.getMapSource() != null) - { - if (targetType.ownMaps()) - { - int i = 1; - mapSource = new GameType[targetType.getMapSource().length + 1]; - for (GameType type : targetType.getMapSource()) - { - mapSource[i] = type; - i++; - } - mapSource[0] = targetType; - } - else - { - mapSource = targetType.getMapSource(); - } - } - - return mapSource; - } - - public String GetMode() - { - return null; - } - - public boolean isAllowingGameStats() - { - return true; - } - - public GameType GetType() - { - return _gameType; - } - - public String[] GetDesc() - { - return _gameDesc; - } - - public void SetCustomWinLine(String line) - { - _customWinLine = line; - } - - public void SetCustomWinMessage(Player player, String message) - { - _customWinMessages.put(player, message); - } - - public GameScoreboard GetScoreboard() - { - return Scoreboard; - } - - public ArrayList GetTeamList() - { - return _teamList; - } - - public GameTeamModule getTeamModule() - { - return _teamModule; - } - - public int GetCountdown() - { - return _countdown; - } - - public void SetCountdown(int time) - { - _countdown = time; - } - - public boolean GetCountdownForce() - { - return _countdownForce; - } - - public void SetCountdownForce(boolean value) - { - _countdownForce = value; - } - - public NautHashMap GetPlayerKits() - { - return _playerKit; - } - - public NautHashMap> GetPlayerGems() - { - return _gemCount; - } - - public Map GetLocationStore() - { - return _playerLocationStore; - } - - public GameState GetState() - { - return _gameState; - } - - public void prepareToRecruit() - { - UtilTabTitle.broadcastHeaderAndFooter(GamePlayerManager.getHeader(this), GamePlayerManager.FOOTER); - - generateTeams(); - recruit(); - } - - public void recruit() - { - SetState(GameState.Recruit); - } - - public void generateTeams() - { - int count = 1; - - for (Entry> entry : WorldData.getAllSpawnLocations().entrySet()) - { - String team = entry.getKey(); - ChatColor color; - - if (team.equalsIgnoreCase("RED")) color = ChatColor.RED; - else if (team.equalsIgnoreCase("YELLOW")) color = ChatColor.YELLOW; - else if (team.equalsIgnoreCase("GREEN")) color = ChatColor.GREEN; - else if (team.equalsIgnoreCase("BLUE")) color = ChatColor.AQUA; - else if (team.equalsIgnoreCase("PINK")) color = ChatColor.LIGHT_PURPLE; - else if (team.equalsIgnoreCase("CYAN")) color = ChatColor.DARK_AQUA; - else if (team.equalsIgnoreCase("PURPLE")) color = ChatColor.DARK_PURPLE; - else if (team.equalsIgnoreCase("ORANGE")) color = ChatColor.GOLD; - else - { - color = ChatColor.DARK_GREEN; - int modulo = GetTeamList().size() % 14; - - if (modulo == 0) if (WorldData.getAllSpawnLocations().size() > 1) color = ChatColor.RED; - if (modulo == 1) color = ChatColor.YELLOW; - if (modulo == 2) color = ChatColor.GREEN; - if (modulo == 3) color = ChatColor.AQUA; - if (modulo == 4) color = ChatColor.GOLD; - if (modulo == 5) color = ChatColor.LIGHT_PURPLE; - if (modulo == 6) color = ChatColor.DARK_BLUE; - if (modulo == 7) color = ChatColor.WHITE; - if (modulo == 8) color = ChatColor.BLUE; - if (modulo == 9) color = ChatColor.DARK_GREEN; - if (modulo == 10) color = ChatColor.DARK_PURPLE; - if (modulo == 11) color = ChatColor.DARK_RED; - if (modulo == 12) color = ChatColor.DARK_AQUA; - } - - //Random Names - String teamName = team; - if (WorldData.getAllSpawnLocations().size() > 12) - { - teamName = String.valueOf(count); - count++; - } - - GameTeam newTeam = new GameTeam(this, teamName, color, entry.getValue()); - AddTeam(newTeam); - } - - //Restrict Kits - RestrictKits(); - - //Parse Data - ParseData(); - } - - public void SetState(GameState state) - { - _gameState = state; - _gameStateTime = System.currentTimeMillis(); - - /* - if (_gameState == Game.GameState.Prepare) - { - - // Speed Builders, Master Builders, Draw My Thing, Castle Siege - if (!AnticheatDisabled) - { - Managers.get(AntiHack.class).enableAnticheat(); - } - - } - else if (_gameState == Game.GameState.End && !this.AnticheatDisabled) - { - Managers.get(AntiHack.class).disableAnticheat(); - } - - */ - - - if (_gameState == GameState.Live) - setGameLiveTime(_gameStateTime); - - for (Player player : UtilServer.getPlayers()) - player.leaveVehicle(); - - - _lifetime.setPhase(state); - - // Event - GameStateChangeEvent stateEvent = new GameStateChangeEvent(this, state); - UtilServer.getServer().getPluginManager().callEvent(stateEvent); - - System.out.println(GetName() + " state set to " + state.toString()); - - if (state.equals(GameState.Prepare)) - { - CoreGameStartEvent coreGameStartEvent = new CoreGameStartEvent(GetType().getDisplay()); - UtilServer.getServer().getPluginManager().callEvent(coreGameStartEvent); - } - else if (state.equals(GameState.End)) - { - CoreGameStopEvent coreGameStopEvent = new CoreGameStopEvent(GetType().getDisplay()); - UtilServer.getServer().getPluginManager().callEvent(coreGameStopEvent); - } - } - - public void SetStateTime(long time) - { - _gameStateTime = time; - } - - public long GetStateTime() - { - return _gameStateTime; - } - - public boolean inLobby() - { - return GetState() == GameState.PreLoad || GetState() == GameState.Loading || GetState() == GameState.Recruit; - } - - public boolean InProgress() - { - return GetState() == GameState.Prepare || GetState() == GameState.Live; - } - - public boolean IsLive() - { - return _gameState == GameState.Live; - } - - public void AddTeam(GameTeam team) - { - // Add - GetTeamList().add(team); - - System.out.println("Created Team: " + team.GetName()); - } - - public void RemoveTeam(GameTeam team) - { - if (GetTeamList().remove(team)) - System.out.println("Deleted Team: " + team.GetName()); - } - - public boolean HasTeam(GameTeam team) - { - for (GameTeam cur : GetTeamList()) - if (cur.equals(team)) - return true; - - return false; - } - - public void RestrictKits() - { - // Null Default - } - - public void RegisterKits() - { - for (Kit kit : _kits) - { - if (kit == null) - { - continue; - } - - kit.registerEvents(); - UtilServer.RegisterEvents(kit); - - if (kit instanceof LinearUpgradeKit) - { - for (Perk[] arrayOfPerks : ((LinearUpgradeKit) kit).getPerks()) - { - for (Perk perk : arrayOfPerks) - { - UtilServer.RegisterEvents(perk); - perk.registeredEvents(); - } - } - } - else - { - for (Perk perk : kit.GetPerks()) - { - UtilServer.getServer().getPluginManager().registerEvents(perk, Manager.getPlugin()); - perk.registeredEvents(); - } - } - } - } - - public void DeregisterKits() - { - for (Kit kit : _kits) - { - if (kit == null) - { - continue; - } - - kit.unregisterEvents(); - HandlerList.unregisterAll(kit); - - if (kit instanceof LinearUpgradeKit) - { - for (Perk[] arrayOfPerks : ((LinearUpgradeKit) kit).getPerks()) - { - for (Perk perk : arrayOfPerks) - { - perk.unregisteredEvents(); - HandlerList.unregisterAll(perk); - } - } - } - else - { - for (Perk perk : kit.GetPerks()) - { - HandlerList.unregisterAll(perk); - perk.unregisteredEvents(); - } - } - - - } - } - - public void ParseData() - { - // Nothing by default, - // Use this to parse in extra location data from maps - } - - public boolean loadNecessaryChunks(long maxMilliseconds) - { - long endTime = System.currentTimeMillis() + maxMilliseconds; - - int minX = WorldData.MinX >> 4; - int minZ = WorldData.MinZ >> 4; - int maxX = WorldData.MaxX >> 4; - int maxZ = WorldData.MaxZ >> 4; - - for (int x = minX; x <= maxX; x++) - { - for (int z = minZ; z <= maxZ; z++) - { - if (System.currentTimeMillis() >= endTime) - return false; - - WorldData.World.getChunkAt(x, z); - } - } - - return true; - } - - public void SetPlayerTeam(Player player, GameTeam team, boolean in) - { - // Clean Old Team - GameTeam pastTeam = this.GetTeam(player); - if (pastTeam != null) - { - pastTeam.RemovePlayer(player); - } - - team.AddPlayer(player, in); - - // Game Scoreboard - Scoreboard.setPlayerTeam(player, team); - - // Lobby Scoreboard - Manager.GetLobby().AddPlayerToScoreboards(player, team); - - // Ensure Valid Kit - ValidateKit(player, team); - } - - public TeamSelector getTeamSelector() - { - return _teamSelector; - } - - public double GetKillsGems(Player killer, Player killed, boolean assist) - { - if (DeathOut) - { - if (!assist) - { - return GemKillDeathOut; - } - else - { - return GemAssistDeathOut; - } - } - else - { - if (!assist) - { - return GemKillDeathRespawn; - } - else - { - return GemAssistDeathRespawn; - } - } - } - - public HashMap GetGems(Player player) - { - if (!_gemCount.containsKey(player)) - _gemCount.put(player, new HashMap<>()); - - return _gemCount.get(player); - } - - public void AddGems(Player player, double gems, String reason, boolean countAmount, boolean multipleAllowed) - { - if (!countAmount && gems < 1) - gems = 1; - - if (GetGems(player).containsKey(reason) && multipleAllowed) - { - GetGems(player).get(reason).AddGems(gems); - } - else - { - GetGems(player).put(reason, new GemData(gems, countAmount)); - } - } - - public void ValidateKit(Player player, GameTeam team) - { - Kit kit = GetKit(player); - - if (kit != null) - { - //Make sure their current kit can be used, if not, tell them. - if (team.KitAllowed(kit)) - { - return; - } - - setFirstKit(player, team, true); - } - else - { - MineplexGameManager gameManager = Manager.getMineplexGameManager(); - - for (Kit otherKit : _kits) - { - KitAvailability availability = otherKit.GetAvailability(); - - if (availability == KitAvailability.Hide || availability == KitAvailability.Null) - { - continue; - } - - if (gameManager.isActive(player, otherKit.getGameKit()) && team.KitAllowed(otherKit)) - { - SetKit(player, otherKit, true); - return; - } - } - - setFirstKit(player, team, false); - } - } - - private void setFirstKit(Player player, GameTeam team, boolean inform) - { - if (inform) - { - player.sendMessage(F.main("Kit", "Your current kit is not applicable with your team. Please select a different kit.")); - } - - Arrays.stream(_kits).filter(team::KitAllowed).findFirst().ifPresent(kit1 -> SetKit(player, kit1, false)); - } - - public void SetKit(Player player, Kit kit, boolean announce) - { - SetKit(player, kit, announce, true); - } - - public void SetKit(Player player, Kit kit, boolean announce, boolean apply) - { - GameTeam team = GetTeam(player); - - if (team != null && !team.KitAllowed(kit)) - { - if (announce) - { - player.playSound(player.getLocation(), Sound.NOTE_BASS, 2f, 0.5f); - player.sendMessage(F.main("Kit", F.elem(team.GetFormattedName()) + " cannot use " + F.elem(kit.GetFormattedName() + " Kit") + ".")); - } - - return; - } - - Kit oldKit = GetKit(player); - - if (oldKit != null) - { - oldKit.Deselected(player); - } - - _playerKit.put(player, kit); - - kit.Selected(player); - - if (announce) - { - player.playSound(player.getLocation(), Sound.ORB_PICKUP, 2f, 1f); - UtilPlayer.message(player, F.main("Kit", "You equipped " + F.elem(kit.GetFormattedName() + " Kit") + ".")); - } - - if (InProgress() && apply) - { - kit.ApplyKit(player); - } - else if (!(kit instanceof ChampionsKit)) - { - UtilPlayer.closeInventoryIfOpen(player); - } - } - - public Kit GetKit(Player player) - { - return _playerKit.get(player); - } - - public Kit[] GetKits() - { - return _kits; - } - - public boolean HasKit(Kit kit) - { - for (Kit cur : GetKits()) - if (cur.equals(kit)) - return true; - - return false; - } - - public boolean HasKit(Player player, Kit kit) - { - Kit playerKit = GetKit(player); - - return IsAlive(player) && playerKit != null && playerKit.equals(kit); - } - - public void disqualify(Player player) - { - _teamModule.getPreferences().remove(player); - GetPlayerKits().remove(player); - GetPlayerGems().remove(player); - - //Remove Team - GameTeam team = GetTeam(player); - if (team != null) - { - if (InProgress()) - { - SetPlayerState(player, PlayerState.OUT); - } - else - { - team.RemovePlayer(player); - } - } - - Manager.addSpectator(player, false); - } - - public boolean SetPlayerState(Player player, PlayerState state) - { - GameTeam team = GetTeam(player); - - if (team == null) - { - return false; - } - - team.SetPlayerState(player, state); - - // Event - UtilServer.CallEvent(new PlayerStateChangeEvent(this, player, state)); - - return true; - } - - public abstract void EndCheck(); - - public void RespawnPlayer(final Player player) - { - player.eject(); - RespawnPlayerTeleport(player); - - Manager.Clear(player); - - // Event - PlayerGameRespawnEvent event = new PlayerGameRespawnEvent(this, player); - UtilServer.getServer().getPluginManager().callEvent(event); - - // Re-set player gamemode - player.setGameMode(PlayerGameMode); - - // Re-Give Kit - Manager.runSyncLater(() -> GetKit(player).ApplyKit(player), 0); - } - - public void RespawnPlayerTeleport(Player player) - { - player.teleport(GetTeam(player).GetSpawn()); - } - - public boolean IsPlaying(Player player) - { - return GetTeam(player) != null; - } - - public boolean IsAlive(Entity entity) - { - if (entity instanceof Player) - { - Player player = (Player) entity; - - GameTeam team = GetTeam(player); - - return team != null && team.IsAlive(player); - } - - return false; - } - - public boolean shouldHeal(Player player) - { - return true; - } - - public ArrayList GetPlayers(boolean aliveOnly) - { - ArrayList players = new ArrayList(); - - for (GameTeam team : _teamList) - players.addAll(team.GetPlayers(aliveOnly)); - - return players; - } - - public GameTeam GetTeam(String player, boolean aliveOnly) - { - for (GameTeam team : _teamList) - if (team.HasPlayer(player, aliveOnly)) - return team; - - return null; - } - - public GameTeam GetTeam(Player player) - { - if (player == null) - return null; - - for (GameTeam team : _teamList) - if (team.HasPlayer(player)) - return team; - - return null; - } - - public GameTeam GetTeam(ChatColor color) - { - for (GameTeam team : _teamList) - if (team.GetColor() == color) - return team; - - return null; - } - - public Location GetSpectatorLocation() - { - if (SpectatorSpawn != null) - return SpectatorSpawn; - - Vector vec = new Vector(0, 0, 0); - double count = 0; - - for (GameTeam team : this.GetTeamList()) - { - for (Location spawn : team.GetSpawns()) - { - count++; - vec.add(spawn.toVector()); - } - } - - SpectatorSpawn = new Location(this.WorldData.World, 0, 0, 0); - - vec.multiply(1d / count); - - SpectatorSpawn.setX(vec.getX()); - SpectatorSpawn.setY(vec.getY()); - SpectatorSpawn.setZ(vec.getZ()); - - // Move Up - Out Of Blocks - while (!UtilBlock.airFoliage(SpectatorSpawn.getBlock()) - || !UtilBlock.airFoliage(SpectatorSpawn.getBlock().getRelative(BlockFace.UP))) - { - SpectatorSpawn.add(0, 1, 0); - } - - int Up = 0; - - // Move Up - Through Air - for (int i = 0; i < 15; i++) - { - if (UtilBlock.airFoliage(SpectatorSpawn.getBlock().getRelative(BlockFace.UP))) - { - SpectatorSpawn.add(0, 1, 0); - Up++; - } - else - { - break; - } - } - - // Move Down - Out Of Blocks - while (Up > 0 && !UtilBlock.airFoliage(SpectatorSpawn.getBlock()) - || !UtilBlock.airFoliage(SpectatorSpawn.getBlock().getRelative(BlockFace.UP))) - { - SpectatorSpawn.subtract(0, 1, 0); - Up--; - } - - SpectatorSpawn = SpectatorSpawn.getBlock().getLocation().add(0.5, 0.1, 0.5); - - while (SpectatorSpawn.getBlock().getTypeId() != 0 || SpectatorSpawn.getBlock().getRelative(BlockFace.UP).getTypeId() != 0) - SpectatorSpawn.add(0, 1, 0); - - return SpectatorSpawn; - } - - @EventHandler - public abstract void ScoreboardUpdate(UpdateEvent event); - - public DeathMessageType GetDeathMessageType() - { - if (!DeathMessages) - return DeathMessageType.None; - - if (this.DeathOut) - return DeathMessageType.Detailed; - - return DeathMessageType.Simple; - } - - @EventHandler - public final void onFoodLevelChangeEvent(FoodLevelChangeEvent event) - { - ((Player) event.getEntity()).setSaturation(5); // While not entirely accurate, this is a pretty good guess at original - // food level changes - } - - public void AnnounceGame() - { - for (Player player : UtilServer.getPlayers()) - AnnounceGame(player); - - if (AnnounceSilence) - Manager.GetChat().setChatSilence(PrepareTime, false); - } - - public void AnnounceGame(Player player) - { - player.playSound(player.getLocation(), Sound.LEVEL_UP, 2f, 1f); - - for (int i = 0; i < 6 - GetDesc().length; i++) - UtilPlayer.message(player, ""); - - UtilPlayer.message(player, ArcadeFormat.Line); - - UtilPlayer.message(player, C.cGreen + "Game - " + C.cYellowB + GetName()); - UtilPlayer.message(player, ""); - - for (String line : this.GetDesc()) - { - UtilPlayer.message(player, C.cWhite + " " + line); - } - - UtilPlayer.message(player, ""); - UtilPlayer.message(player, WorldData.getFormattedName()); - - UtilPlayer.message(player, ArcadeFormat.Line); - } - - public void AnnounceEnd(GameTeam team) - { - if (!IsLive()) - return; - - if (WinEffectEnabled && team != null && !team.GetPlacements(true).isEmpty()) - { - Map teamGemCount = new HashMap<>(); - - List teamList = team.GetPlacements(true).stream() - .filter((p) -> !getArcadeManager().isVanished(p)) - // Get the gem count for each member of the team, - // and save it to the HashMap, so it can be sorted - .peek((p) -> - { - Map gemDataMap = GetGems(p); - - int gemCount = 0; - - for (GemData data : gemDataMap.values()) - { - gemCount += data.Gems; - } - - teamGemCount.put(p, gemCount); - }) - // Sort based on gem count in descending order - .sorted((p1, p2) -> teamGemCount.get(p2) - teamGemCount.get(p1)) - .collect(Collectors.toList()); - - List otherList = UtilServer.getPlayersCollection() - .stream() - .filter((p) -> !getArcadeManager().isVanished(p) && !teamList.contains(p)) - .collect(Collectors.toList()); - - // This sets the "winner" player as the player with the - // most gems, since it's been previously sorted as such - Player player = teamList.remove(0); - - WinEffectManager.prePlay(this, player, teamList, otherList); - - Location loc = GetSpectatorLocation().clone().add(1000, 0, 1000); - loc.setY(200); - WinEffectManager.playWinEffect(loc); - } - - String winnerText = ChatColor.WHITE + "Nobody"; - ChatColor subColor = ChatColor.WHITE; - - for (Player player : UtilServer.getPlayers()) - { - player.playSound(player.getLocation(), Sound.LEVEL_UP, 2f, 1f); - - UtilPlayer.message(player, ""); - UtilPlayer.message(player, ArcadeFormat.Line); - - UtilPlayer.message(player, C.cGreen + "Game - " + C.cYellowB + GetName()); - UtilPlayer.message(player, ""); - UtilPlayer.message(player, ""); - - if (team != null) - { - WinnerTeam = team; - Winner = team.GetName() + " Team"; - - winnerText = team.GetColor() + team.GetName(); - subColor = team.GetColor(); - - UtilPlayer.message(player, subColor + C.Bold + team.GetName() + " won the game!"); - } - else - { - UtilPlayer.message(player, "Nobody won the game!"); - } - - if (_customWinMessages.containsKey(player)) - { - if (!_customWinLine.trim().equalsIgnoreCase("")) - { - UtilPlayer.message(player, _customWinLine); - } - - UtilPlayer.message(player, _customWinMessages.get(player)); - } - else - { - UtilPlayer.message(player, _customWinLine); - } - - UtilPlayer.message(player, ""); - UtilPlayer.message(player, WorldData.getFormattedName()); - - UtilPlayer.message(player, ArcadeFormat.Line); - } - - UtilTextMiddle.display(winnerText, subColor + "won the game", 20, 120, 20); - - if (AnnounceSilence) - Manager.GetChat().setChatSilence(5000, false); - - endElo(); - } - - public void AnnounceEnd(List places) - { - String winnerText = ChatColor.WHITE + "§lNobody won the game..."; - ChatColor subColor = ChatColor.WHITE; - - if (WinEffectEnabled && places != null && !places.isEmpty()) - { - List teamList = new ArrayList<>(); - List nonTeamList = new ArrayList<>(places); - Player player = places.get(0); - nonTeamList.remove(player); - - WinEffectManager.prePlay(this, player, teamList, nonTeamList); - - Location loc = GetSpectatorLocation().clone().add(1000, 0, 1000); - loc.setY(200); - WinEffectManager.playWinEffect(loc); - } - - for (Player player : UtilServer.getPlayers()) - { - player.playSound(player.getLocation(), Sound.LEVEL_UP, 2f, 1f); - - UtilPlayer.message(player, ""); - UtilPlayer.message(player, ArcadeFormat.Line); - - UtilPlayer.message(player, C.cGreen + "Game - " + C.cYellowB + GetName()); - UtilPlayer.message(player, ""); - - if (places == null || places.isEmpty()) - { - UtilPlayer.message(player, ""); - UtilPlayer.message(player, ChatColor.WHITE + "§lNobody won the game..."); - UtilPlayer.message(player, ""); - } - else - { - if (places.size() >= 1) - { - Winner = places.get(0).getName(); - - winnerText = C.cYellow + places.get(0).getName(); - subColor = ChatColor.YELLOW; - - UtilPlayer.message(player, C.cRed + C.Bold + "1st Place" + C.cWhite + " - " + places.get(0).getName()); - } - - if (places.size() >= 2) - { - UtilPlayer.message(player, C.cGold + C.Bold + "2nd Place" + C.cWhite + " - " + places.get(1).getName()); - } - - if (places.size() >= 3) - { - UtilPlayer.message(player, C.cYellow + C.Bold + "3rd Place" + C.cWhite + " - " + places.get(2).getName()); - } - } - - UtilPlayer.message(player, ""); - UtilPlayer.message(player, WorldData.getFormattedName()); - - UtilPlayer.message(player, ArcadeFormat.Line); - } - - UtilTextMiddle.display(winnerText, subColor + "won the game", 20, 120, 20); - - if (AnnounceSilence) - Manager.GetChat().setChatSilence(5000, false); - - endElo(); - } - - public void Announce(String message) - { - if (message == null) - return; - - Announce(message, true); - } - - public void Announce(String message, boolean playSound) - { - for (Player player : UtilServer.getPlayers()) - { - if (playSound) - player.playSound(player.getLocation(), Sound.NOTE_PLING, 1f, 1f); - - UtilPlayer.message(player, message); - } - - System.out.println("[Announcement] " + message); - } - - public boolean AdvertiseText(LobbyManager gameLobbyManager, int _advertiseStage) - { - return false; - } - - public boolean CanThrowTNT(Location location) - { - return true; - } - - @EventHandler - public void HelpUpdate(UpdateEvent event) - { - if (_help == null || _help.length == 0 || event.getType() != UpdateType.SLOWER || !inLobby()) - { - return; - } - - if (Manager.GetGameHostManager().isCommunityServer()) - { - return; - } - - _helpColor = _helpColor == ChatColor.YELLOW ? ChatColor.GOLD : ChatColor.YELLOW; - - String msg = C.cWhiteB+ "TIP> " + ChatColor.RESET + _helpColor + _help[_helpIndex]; - - for (Player player : UtilServer.getPlayersCollection()) - { - if (!Manager.getPreferences().get(player).isActive(Preference.GAME_TIPS)) - { - continue; - } - - player.playSound(player.getLocation(), Sound.CHICKEN_EGG_POP, 1f, 1f); - UtilPlayer.message(player, msg); - } - - _helpIndex = (_helpIndex + 1) % _help.length; - } - - public void StartPrepareCountdown() - { - _prepareCountdown = true; - } - - public boolean CanStartPrepareCountdown() - { - return _prepareCountdown; - } - - @EventHandler - public void TeamPlayerPlacement(PlayerStateChangeEvent event) - { - GameTeam team = GetTeam(event.GetPlayer()); - - if (team != null) - team.SetPlacement(event.GetPlayer(), event.GetState()); - } - - public void HandleTimeout() - { - SetState(GameState.End); - } - - public void AddStat(Player player, String stat, int amount, boolean limitTo1, boolean global) - { - if (!Manager.IsRewardStats()) - return; - - _stats.computeIfAbsent(player, k -> new HashMap<>()); - - if (global) - { - stat = "Global." + stat; - } - else - { - // In certain game modes (for example OP Bridges) we don't want to award game stats but global ones like EXP are fine. - if (!isAllowingGameStats()) - { - return; - } - - stat = GetName() + "." + stat; - } - - if (Manager.IsTournamentServer()) - stat += ".Tournament"; - - int past = 0; - if (_stats.get(player).containsKey(stat)) - past = _stats.get(player).get(stat); - - _stats.get(player).put(stat, limitTo1 ? Math.min(1, past + amount) : past + amount); - } - - public abstract List getWinners(); - - public abstract List getLosers(); - - public Map> GetStats() - { - return _stats; - } - - public void registerStatTrackers(StatTracker... statTrackers) - { - for (StatTracker tracker : statTrackers) - { - if (_statTrackers.add(tracker)) - Bukkit.getPluginManager().registerEvents(tracker, Manager.getPlugin()); - } - } - - public void registerChatStats(ChatStatData... stats) - { - Manager.getGameChatManager().setGameChatStats(stats); - } - - public Collection> getStatTrackers() - { - return _statTrackers; - } - - public void registerMissions(MissionTracker... trackers) - { - getArcadeManager().getMissionsManager().registerTrackers(trackers); - } - - @EventHandler - public void onHangingBreak(HangingBreakEvent event) - { - event.setCancelled(true); - } - - @EventHandler - public void onHangingPlace(HangingPlaceEvent event) - { - event.setCancelled(true); - } - - @EventHandler - public void onDamageHanging(EntityDamageEvent event) - { - if (event.getEntity() instanceof Hanging) - { - event.setCancelled(true); - } - } - - public void deRegisterStats() - { - for (StatTracker tracker : _statTrackers) - HandlerList.unregisterAll(tracker); - - _statTrackers.clear(); - } - - public ArcadeManager getArcadeManager() - { - return Manager; - } - - @EventHandler - public void classCombatCreatureAllow(ClassCombatCreatureAllowSpawnEvent event) - { - CreatureAllowOverride = event.getAllowed(); - } - - public boolean isInsideMap(Player player) - { - return isInsideMap(player.getLocation()); - } - - public boolean isInsideMap(Location loc) - { - return !(loc.getX() >= WorldData.MaxX + 1 || loc.getX() <= WorldData.MinX || loc.getZ() >= WorldData.MaxZ + 1 - || loc.getZ() <= WorldData.MinZ || loc.getY() >= WorldData.MaxY + 1 || loc.getY() <= WorldData.MinY); - } - - public void setItemMerge(boolean itemMerge) - { - setItemMergeRadius(itemMerge ? 3.5 : 0); - } - - public void setItemMergeRadius(double mergeRadius) - { - _itemMergeRadius = mergeRadius; - - if (WorldData.World != null) - { - ((CraftWorld) WorldData.World).getHandle().spigotConfig.itemMerge = _itemMergeRadius; - } - } - - public double getItemMergeRadius() - { - return _itemMergeRadius; - } - - @EventHandler - public void applyItemMerge(WorldLoadEvent event) - { - if (event.getWorld().getName().equals(WorldData.GetFolder())) - { - System.out.println("Setting item merge radius for game to " + _itemMergeRadius); - ((CraftWorld) event.getWorld()).getHandle().spigotConfig.itemMerge = _itemMergeRadius; - } - } - - public void setGame(GameType gameType, Player caller, boolean inform) - { - Manager.GetGameCreationManager().setNextGameType(gameType); - - // End Current - if (inLobby()) - { - SetState(GameState.Dead); - - if (inform) - Announce(C.cAquaB + caller.getName() + " has changed game to " + gameType.getName() + "."); - } - else - { - if (inform) - Announce(C.cAquaB + caller.getName() + " set next game to " + gameType.getName() + "."); - } - } - - public void endGame(GameTeam winningTeam) - { - AnnounceEnd(winningTeam); - - for (GameTeam team : GetTeamList()) - { - if (WinnerTeam != null && team.equals(WinnerTeam)) - { - for (Player player : team.GetPlayers(false)) - AddGems(player, 10, "Winning Team", false, false); - } - - for (Player player : team.GetPlayers(false)) - if (player.isOnline()) - AddGems(player, 10, "Participation", false, false); - } - - endElo(); - - // End - SetState(GameState.End); - } - - @EventHandler - public void onTeleportPrepare(PlayerPrepareTeleportEvent event) - { - event.GetPlayer().setGameMode(PlayerGameMode); - } - - @EventHandler - public void onGameStart(GameStateChangeEvent event) - { - if (event.GetState() == GameState.Live) - { - if (EloRanking) - { - // Populate teams - for (GameTeam team : GetTeamList()) - { - EloTeam eloTeam = new EloTeam(); - - for (Player player : team.GetPlayers(false)) - { - eloTeam.addPlayer(new EloPlayer(player, Manager.GetClients().getAccountId(player), Manager.getEloManager().getElo(player, GetType().getGameId()))); - } - - Manager.getEloManager().addTeam(team.getDisplayName(), eloTeam); - } - } - } - } - - // Handle Elo at end of game -- method can be overridden in different game modes to meet their individual needs - protected void endElo() - { - if (EloRanking) - { - if (WinnerTeam != null) - Manager.getEloManager().setWinningTeam(WinnerTeam.getDisplayName()); - - Manager.getEloManager().endMatch(GetType().getGameId()); - } - } - - - @EventHandler - public void handleInteractEntityPacket(GameStateChangeEvent event) - { - if (event.GetState() == GameState.Live) - { - getArcadeManager().getPacketHandler().addPacketHandler(_useEntityPacketHandler, PacketPlayInUseEntity.class); - } - else if (event.GetState() == GameState.Dead) - { - getArcadeManager().getPacketHandler().removePacketHandler(_useEntityPacketHandler); - } - } - - @EventHandler - public void onDeadBodyDeath(CombatDeathEvent event) - { - if (!IsLive()) - { - return; - } - - if (!(event.GetEvent().getEntity() instanceof Player)) - return; - - if (!DeadBodiesDeath) - { - return; - } - - spawnDeadBody((Player) event.GetEvent().getEntity()); - } - - @EventHandler(priority = EventPriority.LOW) - public void onDeadBodyQuit(PlayerQuitEvent event) - { - if (!IsLive()) - { - return; - } - - if (!IsAlive(event.getPlayer())) - { - return; - } - - if (!DeadBodiesQuit) - { - return; - } - - spawnDeadBody(event.getPlayer()); - } - - private void spawnDeadBody(Player player) - { - if (!DeadBodies) - { - return; - } - - Location loc = player.getLocation(); - String name = "Body #" + ++_deadBodyCount; - - if (UseCustomScoreboard) - { - for (Player other : UtilServer.getPlayersCollection()) - { - setupDeadBodyScoreboard(other.getScoreboard(), name); - } - } - else - { - setupDeadBodyScoreboard(Scoreboard.getScoreboard(), name); - } - - EntityItem entityItem = new EntityItem( - ((CraftWorld) loc.getWorld()).getHandle(), - loc.getX(), - loc.getY() + 0.5, - loc.getZ(), - CraftItemStack.asNMSCopy(new ItemBuilder(Material.STONE).setTitle(System.currentTimeMillis() + "").build()) - ); - entityItem.pickupDelay = Integer.MAX_VALUE; - entityItem.yaw = player.getLocation().getYaw(); - entityItem.pitch = player.getLocation().getPitch(); - - UtilEnt.CreatureLook(entityItem.getBukkitEntity(), player.getLocation().getPitch(), player.getLocation().getYaw()); - - GameProfile profile = UtilGameProfile.getGameProfile(player); - - GameProfile cloned = new GameProfile(UUID.randomUUID(), name); - cloned.getProperties().putAll(profile.getProperties()); - - DisguisePlayer disguise = new DisguisePlayer(entityItem.getBukkitEntity(), cloned); - disguise.setSleeping(getSleepingFace(player.getLocation())); - - _deadBodies.put(player.getName(), entityItem.getBukkitEntity()); - - if (DeadBodiesExpire > 0) - { - _deadBodiesExpire.put(player.getName(), System.currentTimeMillis() + (DeadBodiesExpire * 1000)); - } - - getArcadeManager().GetDisguise().disguise(disguise); - } - - private void setupDeadBodyScoreboard(Scoreboard scoreboard, String name) - { - Team team = scoreboard.getTeam(ChatColor.COLOR_CHAR + "DeadBodies"); - - if (team == null) - { - team = scoreboard.registerNewTeam(ChatColor.COLOR_CHAR + "DeadBodies"); - team.setNameTagVisibility(NameTagVisibility.NEVER); - } - - team.addEntry(name); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onDeadBodyItemSpawn(ItemSpawnEvent event) - { - if (_deadBodies.containsValue(event.getEntity())) - { - event.setCancelled(false); - - ((CraftEntity) event.getEntity()).getHandle().dead = false; - } - } - - public NautHashMap getDeadBodies() - { - return _deadBodies; - } - - public void cleanDeadBodies() - { - for (Entity entity : _deadBodies.values()) - { - entity.remove(); - } - - _deadBodies.clear(); - _deadBodiesExpire.clear(); - _deadBodyCount = 0; - } - - private BlockFace getSleepingFace(Location loc) - { - Block block = loc.getBlock(); - - while (block.getY() > 0 && !UtilBlock.fullSolid(block.getRelative(BlockFace.DOWN)) - && !UtilBlock.solid(block.getRelative(BlockFace.DOWN))) - { - block = block.getRelative(BlockFace.DOWN); - } - - BlockFace proper = BlockFace.values()[Math.round(loc.getYaw() / 90F) & 0x3].getOppositeFace(); - - // A complicated way to get the face the dead body should be towards. - for (HashSet validBlocks : new HashSet[] - { - UtilBlock.blockAirFoliageSet, - UtilBlock.blockPassSet - }) - { - - if (validBlocks.contains((byte) block.getRelative(proper).getTypeId())) - { - return proper; - } - - for (BlockFace face : new BlockFace[] - { - BlockFace.EAST, - BlockFace.SOUTH, - BlockFace.NORTH, - BlockFace.WEST - }) - { - if (validBlocks.contains((byte) block.getRelative(face).getTypeId())) - { - return face; - } - } - } - - return proper; - } - - @EventHandler - public void onDeadBodiesExpire(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC) - { - return; - } - - Iterator> itel = _deadBodiesExpire.entrySet().iterator(); - - while (itel.hasNext()) - { - Entry entry = itel.next(); - - if (entry.getValue() < System.currentTimeMillis()) - { - if (_deadBodies.containsKey(entry.getKey())) - { - _deadBodies.remove(entry.getKey()).remove(); - } - - itel.remove(); - } - } - } - - @EventHandler - public void onJoin(PlayerJoinEvent event) - { - if (!IsLive()) - return; - - if (!JoinInProgress) - return; - - _playerInTime.put(event.getPlayer(), System.currentTimeMillis()); - } - - public long getPlayerIngameTime(Player player) - { - if (_playerInTime.containsKey(player)) - return _playerInTime.get(player); - - return 0; - } - - public void addPlayerInTime(Player player) - { - _playerInTime.put(player, System.currentTimeMillis()); - } - - public void addTutorials() - { - } - - public void disable() - { - cleanupModules(); - cleanupCommands(); - //Managers.get(AntiHack.class).resetIgnoredChecks(); - //Managers.get(AntiHack.class).setStrict(false); - getLifetime().end(); - getStatTrackers().forEach(HandlerList::unregisterAll); - getArcadeManager().getMissionsManager().clearTrackers(tracker -> tracker instanceof GameMissionTracker); - } - - @EventHandler - public void registerLocs(UpdateEvent event) - { - if (!SpeedMeasurement) - return; - - if (event.getType() != UpdateType.TICK) - return; - - for (Player player : GetPlayers(true)) - { - if (!_playerPastLocs.containsKey(player.getUniqueId())) - _playerPastLocs.put(player.getUniqueId(), new LinkedList<>()); - - LinkedList> locList = _playerPastLocs.get(player.getUniqueId()); - locList.add(Triple.of(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ())); - - if (locList.size() > MAX_TICK_SPEED_MEASUREMENT) - locList.removeFirst(); - } - } - - /** - * The players Location while the specified amount of ticks ago - * - * @param player to check - * @param ticksAgo amount of time ago - * @return Location of the specified time - */ - public Location getPastLocation(Player player, int ticksAgo) - { - if (!SpeedMeasurement) - { - throw new IllegalStateException("Speed Measurements are not enabled"); - } - - if (!IsAlive(player)) - { - throw new IllegalArgumentException("this only works for ingame players"); - } - - if (ticksAgo > MAX_TICK_SPEED_MEASUREMENT) - { - throw new IllegalArgumentException("ticksAgo needs to be 1 - 40"); - } - - if (!_playerPastLocs.containsKey(player.getUniqueId())) - return player.getLocation(); - - int tick = MAX_TICK_SPEED_MEASUREMENT - ticksAgo; - - LinkedList> pastLocs = _playerPastLocs.get(player.getUniqueId()); - if (pastLocs.size() < tick) - return player.getLocation(); - - Triple triple = _playerPastLocs.get(player.getUniqueId()).get(tick); - return new Location(player.getWorld(), triple.getLeft(), triple.getMiddle(), triple.getRight(), player.getLocation().getYaw(), player.getLocation().getPitch()); - } - - /** - * The Vector of movement for the specified time - * - * @param player to check - * @param ticksAgo amount of time ago - * @return vector of movement - */ - public Vector getMovement(Player player, int ticksAgo) - { - Location past = getPastLocation(player, ticksAgo); - return player.getLocation().toVector().subtract(past.clone().toVector()); - } - - /** - * The amount of blocks moved for the specified time - * - * @param player - * @param ticksAgo amount of time ago - * @return blocks moved - */ - public double getSpeed(Player player, int ticksAgo) - { - Location past = getPastLocation(player, ticksAgo); - return UtilMath.offset(past, player.getLocation()); - } - - public void cleanupModules() - { - for (Module module : this._modules.values()) - { - module.cleanup(); - HandlerList.unregisterAll(module); - } - this._modules.clear(); - } - - public void cleanupCommands() - { - _debugCommands.forEach(command -> CommandCenter.Instance.removeCommand(command)); - _debugCommands.clear(); - } - - public T getModule(Class clazz) - { - return clazz.cast(_modules.get(clazz)); - } - - @Override - public PhasedLifetime getLifetime() - { - return _lifetime; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/GameComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/GameComponent.java deleted file mode 100644 index 2dba42c0..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/GameComponent.java +++ /dev/null @@ -1,37 +0,0 @@ -package nautilus.game.arcade.game; - -import mineplex.core.lifetimes.Lifetime; -import mineplex.core.lifetimes.Lifetimed; -import mineplex.core.lifetimes.ListenerComponent; - -import java.util.Arrays; - -public class GameComponent extends ListenerComponent implements Lifetimed -{ - private final Lifetime _lifetime; - private final T _game; - - public GameComponent(T game, Game.GameState...active) - { - _game = game; - if (active == null || active.length == 0) - { - // Active for the entire duration of the game. - _lifetime = game.getLifetime(); - _lifetime.register(this); - } else - { - _lifetime = game.getLifetime().register(this, Arrays.asList(active)); - } - } - - @Override - public Lifetime getLifetime() - { - return _lifetime; - } - - public T getGame() { - return _game; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/GameServerConfig.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/GameServerConfig.java deleted file mode 100644 index d3b12c36..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/GameServerConfig.java +++ /dev/null @@ -1,57 +0,0 @@ -package nautilus.game.arcade.game; - -import java.util.ArrayList; -import java.util.HashMap ; - -import nautilus.game.arcade.GameType; - -public class GameServerConfig -{ - public String ServerGroup = null; - public String ServerType = null; - public String BoosterGroup = null; - public int MinPlayers = -1; - public int MaxPlayers = -1; - - public String Uptimes; - - public final ArrayList GameList = new ArrayList<>(); - public final ArrayList GameModeList = new ArrayList<>(); - - //Flags - public String HostName = ""; - - public boolean Tournament = false; - - public boolean TournamentPoints = false; - - public boolean TeamRejoin = false; - public boolean TeamAutoJoin = true; - public boolean TeamForceBalance = true; - - public boolean GameAutoStart = true; - public boolean GameTimeout = true; - - public boolean RewardGems = true; - public boolean RewardItems = true; - public boolean RewardStats = true; - public boolean RewardAchievements = true; - - public boolean HotbarInventory = true; - public boolean HotbarHubClock = true; - - public boolean PlayerKickIdle = true; - public boolean HardMaxPlayerCap = false; - - public boolean PublicServer = true; - - public boolean PlayerServerWhitelist = false; - - public boolean GameVoting = false; - public boolean MapVoting = false; - - public boolean IsValid() - { - return ServerType != null && MinPlayers != -1 && MaxPlayers != -1; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/GameTeam.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/GameTeam.java deleted file mode 100644 index 768644b1..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/GameTeam.java +++ /dev/null @@ -1,470 +0,0 @@ -package nautilus.game.arcade.game; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Color; -import org.bukkit.DyeColor; -import org.bukkit.Location; -import org.bukkit.entity.Creature; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -import mineplex.core.Managers; -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.game.kit.KitAvailability; -import mineplex.core.visibility.VisibilityManager; - -import nautilus.game.arcade.gametutorial.GameTutorial; -import nautilus.game.arcade.kit.Kit; - -public class GameTeam -{ - private static final AtomicLong TEAM_ID = new AtomicLong(); - - private final Game Host; - - private double _respawnTime = 0; - - public enum PlayerState - { - IN("In"), - OUT("Out"); - - private final String _name; - - PlayerState(String name) - { - _name = name; - } - - public String GetName() - { - return _name; - } - } - - private final long _teamId = TEAM_ID.getAndIncrement(); - - private String _name; - private String _displayName; - private ChatColor _color; - private boolean _displayTag; - - private GameTutorial _tutorial; - - private final Map _players = new HashMap<>(); - - private List _spawns; - - private Creature _teamEntity = null; - - private final Set _kitRestrict = new HashSet<>(); - - private boolean _visible = true; - - //Records order players go out in - private List _places = new ArrayList<>(); - private long _teamCreatedTime = System.currentTimeMillis(); // Used just for SpectatorPage so that teams remain ordered - - public GameTeam(Game host, String name, ChatColor color, List spawns, boolean tags) - { - Host = host; - - _displayName = null; - _name = name; - _color = color; - _spawns = spawns; - _displayTag = tags; - } - - public GameTeam(Game host, String name, ChatColor color, List spawns) - { - this(host, name, color, spawns, false); - } - - public long getCreatedTime() - { - return _teamCreatedTime; - } - - public String GetName() - { - return _name; - } - - public ChatColor GetColor() - { - return _color; - } - - public List GetSpawns() - { - return _spawns; - } - - private Location fixFacing(Location loc) - { - if (Host.FixSpawnFacing) - { - float yaw = UtilAlg.GetYaw(UtilAlg.getTrajectory2d(loc, Host.GetSpectatorLocation())); - - yaw = (int) (yaw / 90) * 90; - - loc = loc.clone(); - loc.setYaw(yaw); - } - - return loc; - } - - public Location GetSpawn() - { - //Keep allies together - if (!Host.IsLive() && Host.SpawnNearAllies) - { - //Find Location Nearest Ally - Location loc = UtilAlg.getLocationNearPlayers(_spawns, GetPlayers(true), Host.GetPlayers(true)); - if (loc != null) - return fixFacing(loc); - - //No allies existed spawned yet - - //Spawn near enemies (used for SG) - if (Host.SpawnNearEnemies) - { - loc = UtilAlg.getLocationNearPlayers(_spawns, Host.GetPlayers(true), Host.GetPlayers(true)); - if (loc != null) - return fixFacing(loc); - } - //Spawn away from enemies - else - { - loc = UtilAlg.getLocationAwayFromPlayers(_spawns, Host.GetPlayers(true)); - if (loc != null) - return fixFacing(loc); - } - } - else - { - //Spawn near players - if (Host.SpawnNearEnemies) - { - Location loc = UtilAlg.getLocationNearPlayers(_spawns, Host.GetPlayers(true), Host.GetPlayers(true)); - if (loc != null) - return fixFacing(loc); - } - //Spawn away from players - else - { - Location loc = UtilAlg.getLocationAwayFromPlayers(_spawns, Host.GetPlayers(true)); - if (loc != null) - return fixFacing(loc); - } - } - - return fixFacing(_spawns.get(UtilMath.r(_spawns.size()))); - } - - public void AddPlayer(Player player, boolean in) - { - _players.put(player, in ? PlayerState.IN : PlayerState.OUT); - - UtilPlayer.message(player, F.main("Team", _color + C.Bold + "You joined " + getDisplayName() + " Team.")); - - VisibilityManager vm = Managers.require(VisibilityManager.class); - Bukkit.getOnlinePlayers().forEach(pl -> vm.refreshVisibility(pl, player)); - } - - public void DisbandTeam() - { - for (Player player : _players.keySet()) - { - Host.getArcadeManager().GetLobby().RemovePlayerFromTeam(player, this); - UtilPlayer.message(player, F.main("Team", _color + C.Bold + getDisplayName() + " Team was disbanded.")); - } - - _players.clear(); - } - - public void RemovePlayer(Player player) - { - _players.remove(player); - } - - public boolean HasPlayer(Player player) - { - return _players.containsKey(player); - } - - public boolean HasPlayer(String name, boolean alive) - { - for (Player player : _players.keySet()) - if (player.getName().equals(name)) - if (!alive || _players.get(player) == PlayerState.IN) - return true; - - return false; - } - - public int GetSize() - { - return _players.size(); - } - - public void SetPlayerState(Player player, PlayerState state) - { - if (player == null) - return; - - _players.put(player, state); - } - - public boolean IsTeamAlive() - { - for (PlayerState state : _players.values()) - if (state == PlayerState.IN) - return true; - - return false; - } - - public ArrayList GetPlayers(boolean playerIn) - { - ArrayList alive = new ArrayList<>(); - - for (Player player : _players.keySet()) - if (!playerIn || (_players.get(player) == PlayerState.IN && player.isOnline())) - alive.add(player); - - return alive; - } - - public String GetFormattedName() - { - return GetColor() + "§l" + GetName(); - } - - public Location SpawnTeleport(Player player) - { - Location l = GetSpawn(); - player.teleport(l); - return l; - } - - public void SpawnTeleport(Player player, Location location) - { - player.leaveVehicle(); - player.eject(); - player.teleport(location); - } - - public void SpawnTeleport() - { - SpawnTeleport(true); - } - - public void SpawnTeleport(boolean aliveOnly) - { - for (Player player : GetPlayers(aliveOnly)) - { - SpawnTeleport(player); - } - } - - public Set GetRestrictedKits() - { - return _kitRestrict; - } - - public boolean KitAllowed(Kit kit) - { - return kit.GetAvailability() != KitAvailability.Null && !_kitRestrict.contains(kit); - } - - public boolean IsAlive(Player player) - { - return player.isOnline() && _players.getOrDefault(player, PlayerState.OUT) == PlayerState.IN; - - } - - public void SetColor(ChatColor color) - { - _color = color; - } - - public void SetName(String name) - { - _name = name; - } - - public void setDisplayName(String name) - { - _displayName = name; - } - - public String getDisplayName() - { - if (_displayName == null) - return _name; - - return _displayName; - } - - public byte GetColorData() - { - if (GetColor() == ChatColor.WHITE) return (byte) 0; - if (GetColor() == ChatColor.GOLD) return (byte) 1; - if (GetColor() == ChatColor.LIGHT_PURPLE) return (byte) 2; - if (GetColor() == ChatColor.AQUA) return (byte) 3; - if (GetColor() == ChatColor.YELLOW) return (byte) 4; - if (GetColor() == ChatColor.GREEN) return (byte) 5; - if (GetColor() == ChatColor.LIGHT_PURPLE) return (byte) 6; - if (GetColor() == ChatColor.DARK_GRAY) return (byte) 7; - if (GetColor() == ChatColor.GRAY) return (byte) 8; - if (GetColor() == ChatColor.DARK_AQUA) return (byte) 9; - if (GetColor() == ChatColor.DARK_PURPLE) return (byte) 10; - if (GetColor() == ChatColor.BLUE) return (byte) 11; - if (GetColor() == ChatColor.DARK_BLUE) return (byte) 11; - //if (GetColor() == ChatColor.BROWN) return (byte)12; - if (GetColor() == ChatColor.DARK_GREEN) return (byte) 13; - if (GetColor() == ChatColor.RED) return (byte) 14; - if (GetColor() == ChatColor.DARK_RED) return (byte) 14; - else return (byte) 15; - } - - public Color GetColorBase() - { - if (GetColor() == ChatColor.WHITE) return Color.WHITE; - if (GetColor() == ChatColor.GOLD) return Color.ORANGE; - if (GetColor() == ChatColor.LIGHT_PURPLE) return Color.FUCHSIA; - if (GetColor() == ChatColor.AQUA) return Color.AQUA; - if (GetColor() == ChatColor.YELLOW) return Color.YELLOW; - if (GetColor() == ChatColor.GREEN) return Color.GREEN; - if (GetColor() == ChatColor.DARK_GRAY) return Color.GRAY; - if (GetColor() == ChatColor.GRAY) return Color.GRAY; - if (GetColor() == ChatColor.DARK_AQUA) return Color.AQUA; - if (GetColor() == ChatColor.DARK_PURPLE) return Color.PURPLE; - if (GetColor() == ChatColor.BLUE) return Color.BLUE; - if (GetColor() == ChatColor.DARK_BLUE) return Color.BLUE; - if (GetColor() == ChatColor.DARK_GREEN) return Color.GREEN; - if (GetColor() == ChatColor.RED) return Color.RED; - else return Color.WHITE; - } - - public DyeColor getDyeColor() - { - if (GetColor() == ChatColor.WHITE) return DyeColor.WHITE; - if (GetColor() == ChatColor.GOLD) return DyeColor.ORANGE; - if (GetColor() == ChatColor.LIGHT_PURPLE) return DyeColor.PINK; - if (GetColor() == ChatColor.AQUA) return DyeColor.LIGHT_BLUE; - if (GetColor() == ChatColor.YELLOW) return DyeColor.YELLOW; - if (GetColor() == ChatColor.GREEN) return DyeColor.LIME; - if (GetColor() == ChatColor.DARK_GRAY) return DyeColor.GRAY; - if (GetColor() == ChatColor.GRAY) return DyeColor.SILVER; - if (GetColor() == ChatColor.DARK_AQUA) return DyeColor.CYAN; - if (GetColor() == ChatColor.DARK_PURPLE) return DyeColor.PURPLE; - if (GetColor() == ChatColor.BLUE) return DyeColor.BLUE; - if (GetColor() == ChatColor.DARK_BLUE) return DyeColor.BLUE; - if (GetColor() == ChatColor.DARK_GREEN) return DyeColor.GREEN; - if (GetColor() == ChatColor.RED) return DyeColor.RED; - else return DyeColor.WHITE; - } - - public void SetTeamEntity(Creature ent) - { - _teamEntity = ent; - } - - public LivingEntity GetTeamEntity() - { - return _teamEntity; - } - - public void SetSpawns(List spawns) - { - _spawns = spawns; - } - - public void SetVisible(boolean b) - { - _visible = b; - } - - public boolean GetVisible() - { - return _visible; - } - - /* - * Whether this GameTeam should show a prefix - */ - public boolean GetDisplaytag() - { - return _displayTag; - } - - public void SetRespawnTime(double i) - { - _respawnTime = i; - } - - public double GetRespawnTime() - { - return _respawnTime; - } - - public void SetPlacement(Player player, PlayerState state) - { - if (state == PlayerState.OUT) - { - if (!_places.contains(player)) - _places.add(0, player); - } - else - _places.remove(player); - } - - public List GetPlacements(boolean includeAlivePlayers) - { - if (includeAlivePlayers) - { - ArrayList placesClone = new ArrayList<>(_places); - - for (Player player : GetPlayers(true)) - { - placesClone.add(0, player); - } - - return placesClone; - } - - return _places; - } - - public GameTutorial getTutorial() - { - return _tutorial; - } - - public void setTutorial(GameTutorial tutorial) - { - _tutorial = tutorial; - } - - public long getTeamId() - { - return this._teamId; - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/GemData.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/GemData.java deleted file mode 100644 index 53c2659d..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/GemData.java +++ /dev/null @@ -1,23 +0,0 @@ -package nautilus.game.arcade.game; - -public class GemData -{ - public double Gems; - public int Amount; - - public GemData(double gems, boolean amount) - { - Gems = gems; - - if (amount) - Amount = 1; - } - - public void AddGems(double gems) - { - Gems += gems; - - if (Amount > 0) - Amount++; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/RankedTeamGame.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/RankedTeamGame.java deleted file mode 100644 index 8165c40f..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/RankedTeamGame.java +++ /dev/null @@ -1,119 +0,0 @@ -package nautilus.game.arcade.game; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.AsyncPlayerPreLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; -import org.bukkit.event.player.PlayerQuitEvent; - -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilTime; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.PlayerPrepareTeleportEvent; -import nautilus.game.arcade.kit.Kit; - -/** - * Wrapper for team games to implement for simple universal use of Elo and Ranked methods. - */ -public abstract class RankedTeamGame extends TeamGame -{ - public int MaxPlayers = -1; - public int MaxPerTeam = -1; - - public RankedTeamGame(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc) - { - super(manager, gameType, kits, gameDesc); - - this.EloRanking = true; - this.SpectatorAllowed = false; - } - - private int getAccountId(UUID uuid) - { - final List id = new ArrayList<>(); - Manager.GetClients().getRepository().getAccountId(uuid, data -> - { - id.add(data); - }); - - if (id.isEmpty()) - { - id.add(0); - } - - return id.get(0); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onTeleport(PlayerPrepareTeleportEvent event) - { - if (GetTeam(event.GetPlayer()).GetPlayers(true).size() > MaxPerTeam) - { - if (MaxPerTeam != -1) - { - disqualify(event.GetPlayer()); - event.GetPlayer().sendMessage(F.main("Game", "This game has reached maximum capacity!")); - return; - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onLogin(AsyncPlayerPreLoginEvent event) - { - long expiry = Manager.getEloManager().getRankBanExpiry(getAccountId(event.getUniqueId())); - if (Manager.getEloManager().checkRankBanned(getAccountId(event.getUniqueId()))) - { - String time = UtilTime.MakeStr(expiry - System.currentTimeMillis()); - String message = ChatColor.RED + "You cannot join a ranked match yet because you left your last one early! Your ban expires in " + time; - event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, message); - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onLogin(PlayerLoginEvent event) - { - if (MaxPlayers == -1) - { - return; - } - if (Bukkit.getOnlinePlayers().size() < MaxPlayers) - { - return; - } - String message = ChatColor.RED + "This game has reached maximum capacity!"; - if (Manager.GetClients().Get(event.getPlayer().getUniqueId()).hasPermission(ArcadeManager.Perm.INFORM_RANKED_MODERATION_POTENTIAL)) - { - if (InProgress()) - { - return; - } - else - { - message += " You may join for moderation purposes after the game has started!"; - } - } - event.disallow(Result.KICK_OTHER, message); - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onQuit(PlayerQuitEvent event) - { - if (InProgress()) - { - if (Manager.hasBeenPlaying(event.getPlayer())) - { - Manager.getEloManager().banFromRanked(getAccountId(event.getPlayer().getUniqueId())); - } - } - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/SoloGame.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/SoloGame.java deleted file mode 100644 index ad369ca9..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/SoloGame.java +++ /dev/null @@ -1,161 +0,0 @@ -package nautilus.game.arcade.game; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; - -import mineplex.core.common.util.C; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.kit.Kit; - -public abstract class SoloGame extends Game -{ - protected GameTeam _players; - - public SoloGame(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc) - { - super(manager, gameType, kits, gameDesc); - } - - @EventHandler - public void CustomTeamGeneration(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Recruit) - return; - - _players = GetTeamList().get(0); - _players.SetColor(ChatColor.YELLOW); - _players.SetName("Players"); - } - - public GameTeam getPlayersTeam() - { - return _players; - } - - @Override - public void EndCheck() - { - if (!IsLive()) - return; - - if (GetPlayers(true).size() <= 1) - { - List places = _players.GetPlacements(true); - - //Announce - AnnounceEnd(places); - - //Gems - if (places.size() >= 1) - AddGems(places.get(0), 20, "1st Place", false, false); - - if (places.size() >= 2) - AddGems(places.get(1), 15, "2nd Place", false, false); - - if (places.size() >= 3) - AddGems(places.get(2), 10, "3rd Place", false, false); - - for (Player player : GetPlayers(false)) - if (player.isOnline()) - AddGems(player, 10, "Participation", false, false); - - //End - SetState(GameState.End); - } - } - - @Override - @EventHandler - public void ScoreboardUpdate(UpdateEvent event) - { - if (event.getType() != UpdateType.FAST) - return; - - if (GetTeamList().isEmpty()) - return; - - Scoreboard.reset(); - - Scoreboard.writeNewLine(); - - GameTeam team = GetTeamList().get(0); - - if (team.GetPlayers(false).size() < 15) - { - for (Player player : team.GetPlayers(false)) - { - if (team.IsAlive(player)) - { - Scoreboard.write(C.cGreen + player.getName()); - } - else - { - Scoreboard.write(C.cGray + player.getName()); - } - } - } - else if (team.GetPlayers(true).size() < 16) - { - for (Player player : team.GetPlayers(true)) - { - Scoreboard.write(C.cGreen + player.getName()); - } - } - else - { - Scoreboard.write(C.cGreen + "Players Alive"); - Scoreboard.write("" + team.GetPlayers(true).size()); - - Scoreboard.writeNewLine(); - Scoreboard.write(C.cRed + "Players Dead"); - Scoreboard.write("" + (team.GetPlayers(false).size() - team.GetPlayers(true).size())); - } - - Scoreboard.draw(); - } - - public int GetScoreboardScore(Player player) - { - return 0; - } - - @Override - public List getWinners() - { - if (GetState().ordinal() >= GameState.End.ordinal()) - { - List places = _players.GetPlacements(true); - - if (places.isEmpty() || !places.get(0).isOnline()) - return Arrays.asList(); - else - return Arrays.asList(places.get(0)); - } - else - return null; - } - - @Override - public List getLosers() - { - List winners = getWinners(); - - if (winners == null) - return null; - - List losers = _players.GetPlayers(false); - - losers.removeAll(winners); - - return losers; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/TeamGame.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/TeamGame.java deleted file mode 100644 index c6cc56ca..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/TeamGame.java +++ /dev/null @@ -1,162 +0,0 @@ -package nautilus.game.arcade.game; - -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.PlayerStateChangeEvent; -import nautilus.game.arcade.game.GameTeam.PlayerState; -import nautilus.game.arcade.kit.Kit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.ArrayList; -import java.util.List; - -public abstract class TeamGame extends Game -{ - protected ArrayList _places = new ArrayList(); - - public TeamGame(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc) - { - super(manager, gameType, kits, gameDesc); - } - - @EventHandler - public void EndStateChange(PlayerStateChangeEvent event) - { - GameTeam team = this.GetTeam(event.GetPlayer()); - if (team == null) - return; - - if (event.GetState() == PlayerState.OUT) - if (!team.IsTeamAlive()) - _places.add(0, team); - - else - _places.remove(team); - } - - public ArrayList GetPlaces() - { - return _places; - } - - @EventHandler(priority = EventPriority.LOW) - public void PlayerQuit(PlayerQuitEvent event) - { - if (!InProgress()) - return; - - Player player = event.getPlayer(); - - GameTeam team = GetTeam(player); - if (team == null) return; - - if (!team.IsAlive(player)) - return; - - team.RemovePlayer(player); - } - - public void EndCheck() - { - if (!IsLive()) - return; - - ArrayList teamsAlive = new ArrayList(); - - for (GameTeam team : this.GetTeamList()) - if (team.GetPlayers(true).size() > 0) - teamsAlive.add(team); - - if (teamsAlive.size() <= 1) - { - //Announce - if (teamsAlive.size() > 0) - AnnounceEnd(teamsAlive.get(0)); - - for (GameTeam team : GetTeamList()) - { - if (WinnerTeam != null && team.equals(WinnerTeam)) - { - for (Player player : team.GetPlayers(false)) - AddGems(player, 10, "Winning Team", false, false); - } - - for (Player player : team.GetPlayers(false)) - if (player.isOnline()) - AddGems(player, 10, "Participation", false, false); - } - - //End - SetState(GameState.End); - } - } - - @Override - @EventHandler - public void ScoreboardUpdate(UpdateEvent event) - { - if (event != null && event.getType() != UpdateType.FAST) - return; - - Scoreboard.reset(); - - for (GameTeam team : this.GetTeamList()) - { - //Display Individual Players - if (this.GetPlayers(true).size() < 13) - { - if (!team.IsTeamAlive()) - continue; - - Scoreboard.writeNewLine(); - - for (Player player : team.GetPlayers(true)) - { - Scoreboard.write(team.GetColor() + player.getName()); - } - } - - //Display Players Alive - else - { - Scoreboard.writeNewLine(); - - Scoreboard.write(team.GetColor() + team.GetName()); - Scoreboard.write(team.GetPlayers(true).size() + "" + team.GetColor() + " Alive"); - } - } - - Scoreboard.draw(); - } - - @Override - public List getWinners() - { - if (WinnerTeam == null) - return null; - - return WinnerTeam.GetPlayers(false); - } - - @Override - public List getLosers() - { - if (WinnerTeam == null) - return null; - - List players = new ArrayList<>(); - - for (GameTeam team : GetTeamList()) - { - if (team != WinnerTeam) - players.addAll(team.GetPlayers(false)); - } - - return players; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/AbsorptionFix.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/AbsorptionFix.java deleted file mode 100644 index d8970a30..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/AbsorptionFix.java +++ /dev/null @@ -1,36 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -public class AbsorptionFix extends Module -{ - - @EventHandler - public void convertAbsorption(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC) - { - return; - } - - for (Player player : getGame().GetPlayers(true)) - { - for (PotionEffect effect : player.getActivePotionEffects()) - { - if (effect.getType().toString().equalsIgnoreCase(PotionEffectType.ABSORPTION.toString())) - { - player.removePotionEffect(PotionEffectType.ABSORPTION); - player.addPotionEffect(new PotionEffect(PotionEffectType.HEALTH_BOOST, effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles())); - UtilPlayer.health(player, 4); - } - } - } - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/AntiExpOrbModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/AntiExpOrbModule.java deleted file mode 100644 index 6928d08f..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/AntiExpOrbModule.java +++ /dev/null @@ -1,100 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import nautilus.game.arcade.game.Game; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.ExperienceOrb; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityTargetLivingEntityEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -/* - * This module will prevent spectators from picking up xp orbs - * - * fixme: there are still some graphical glitches - */ -public class AntiExpOrbModule extends Module -{ - private Set _playersLastUpdated = new HashSet<>(); - - @EventHandler - public void on(UpdateEvent event) - { - if (event.getType() != UpdateType.TICK) - return; - - Game game = getGame(); - - for (Player player : Bukkit.getOnlinePlayers()) - { - boolean disallow = game.GetState() != Game.GameState.Live || !game.IsAlive(player); - - if (disallow) - { - updateTimer(player, 86000); - _playersLastUpdated.add(player.getUniqueId()); - } - else - { - if (_playersLastUpdated.remove(player.getUniqueId())) - { - updateTimer(player, 2); - } - } - } - } - - @EventHandler - public void on(EntityTargetLivingEntityEvent event) - { - if (event.getEntity() instanceof ExperienceOrb) - { - if (event.getTarget() instanceof Player) - { - Player player = (Player) event.getTarget(); - - Game game = getGame(); - - if (game.GetState() != Game.GameState.Live || !game.IsAlive(player)) - { - // Setting the target to null sets the actual target in EntityExperienceOrb to null - event.setTarget(null); - // Cancelling the event is a sanity check - event.setCancelled(true); - } - } - } - } - - @EventHandler - public void on(PlayerQuitEvent event) - { - _playersLastUpdated.remove(event.getPlayer().getUniqueId()); - } - - @Override - public void cleanup() - { - for (UUID uuid : _playersLastUpdated) - { - Player player = Bukkit.getPlayer(uuid); - if (player != null) - { - updateTimer(player, 0); - } - } - _playersLastUpdated.clear(); - } - - private void updateTimer(Player player, int ticksToWait) - { - ((CraftPlayer) player).getHandle().bp = ticksToWait; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ChampionsModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ChampionsModule.java deleted file mode 100644 index 8170ef35..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ChampionsModule.java +++ /dev/null @@ -1,167 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.BlockDamageEvent; -import org.bukkit.event.entity.EntityShootBowEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType; - -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.classcombat.Skill.Skill; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.events.PlayerKitApplyEvent; - -public class ChampionsModule extends Module -{ - @EventHandler(priority = EventPriority.HIGHEST) - public void fixDwarf(PlayerKitApplyEvent event) - { - if (!getGame().IsLive()) - return; - - if (event.isCancelled()) - return; - - if (event.getPlayer().getPassenger() == null) - return; - - event.setCancelled(true); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void fixBlizzard(PlayerKitApplyEvent event) - { - if (!getGame().IsLive()) - { - return; - } - - if (event.isCancelled()) - { - return; - } - - getGame().Manager.getClassManager().GetSkillFactory().GetSkill("Blizzard").Reset(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void fixFlash(PlayerKitApplyEvent event) - { - if (!getGame().IsLive()) - { - return; - } - - if (event.isCancelled()) - { - return; - } - - getGame().Manager.getClassManager().GetSkillFactory().GetSkill("Flash").Reset(event.getPlayer()); - } - - @EventHandler - public void resetSkillsWhileInInventory(UpdateEvent event) - { - if (!getGame().IsLive()) - { - return; - } - - if (event.getType() != UpdateType.FAST) - { - return; - } - - for (Player player : UtilServer.getPlayers()) - { - if (player.getOpenInventory() == null || player.getOpenInventory().getTopInventory() == null) - { - continue; - } - - if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CHEST) - { - for (Skill skill : getGame().Manager.getClassManager().GetSkillFactory().GetAllSkills()) - { - skill.Reset(player); - } - } - } - } - - @EventHandler - public void fixAxe(BlockDamageEvent event) - { - if (!getGame().IsLive()) - { - return; - } - - event.setCancelled(true); - } - - @EventHandler - public void fixArmor(InventoryClickEvent event) - { - event.setCancelled(true); - } - - @EventHandler - public void WaterArrowCancel(EntityShootBowEvent event) - { - if (event.getEntity().getLocation().getBlock().isLiquid()) - { - UtilPlayer.message(event.getEntity(), F.main("Game", "You cannot use your Bow while swimming.")); - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void InventoryDamageCancel(CustomDamageEvent event) - { - if (event.IsCancelled()) - { - return; - } - - Player player = event.GetDamageePlayer(); - if (player == null) - { - return; - } - - if (!getGame().IsAlive(player)) - { - return; - } - - if (player.getOpenInventory() == null || player.getOpenInventory().getTopInventory() == null) - { - return; - } - - if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CHEST) - { - player.closeInventory(); - } - } - - @EventHandler - public void validateSkills(UpdateEvent event) - { - if (event.getType() == UpdateType.SEC) - { - for (Player player : getGame().GetPlayers(true)) - { - getGame().Manager.getClassManager().Get(player).validateClassSkills(player); - } - } - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/CustomScoreboardModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/CustomScoreboardModule.java deleted file mode 100644 index 26bce25e..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/CustomScoreboardModule.java +++ /dev/null @@ -1,412 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.NameTagVisibility; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Score; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; - -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.games.moba.Moba; -import nautilus.game.arcade.scoreboard.GameScoreboard; - -/** - * CustomScoreboardModule allows for the use of per-player scoreboards in an Arcade game. - * Including sidebars, tab-list prefixes, suffixes, undernames and scores.
- * These scoreboard system is backed by {@link mineplex.core.scoreboard.ScoreboardManager} and is thus optimised - * extremely efficiently, so don't be afraid to call the set methods often as they will not be updated then and there.
- * Scoreboards are refreshed for all players upon the prepare, live and end state changes. While sidebars are updated every 10 ticks/0.5 seconds.
- * If you wish to update the scoreboard more frequently than these, the methods: - *

    - *
  • {@link #refresh()}
  • - *
  • {@link #refreshAsPerspective(Player)}
  • - * - *
- * - * @see mineplex.core.scoreboard.MineplexScoreboard - * @see Moba - */ -public class CustomScoreboardModule extends Module -{ - - private final Map _scoreboard; - - private BiConsumer _scoreboardConsumer; - private BiFunction _prefixFunction; - private BiFunction _suffixFunction; - private BiFunction _nameTagVisibilityFunction; - private BiFunction _tabListFunction; - private String _underNameObjective; - private BiFunction _underNameFunction; - - public CustomScoreboardModule() - { - _scoreboard = new HashMap<>(); - } - - /** - * The use of the boolean UseCustomScoreboard in {@link nautilus.game.arcade.game.Game} is required so the Arcade doesn't - * try and create the scoreboard itself or reference the standard {@link GameScoreboard}, which it does (a lot). - */ - @Override - protected void setup() - { - getGame().UseCustomScoreboard = true; - } - - /** - * Calls {@link #setupScoreboard(Player)} when the players joins, if the game is not in a Lobby state. - */ - @EventHandler - public void playerJoin(PlayerJoinEvent event) - { - Player player = event.getPlayer(); - - if (getGame().inLobby()) - { - return; - } - - setupScoreboard(player); - refreshAsPerspective(player); - refreshAsSubject(player); - } - - /** - * Removes the player's scoreboard from the {@link #_scoreboard} map. - *
- * Unregisters the quitting player's entries from all other scoreboards. - */ - @EventHandler - public void playerQuit(PlayerQuitEvent event) - { - Player player = event.getPlayer(); - - _scoreboard.remove(player.getUniqueId()); - - for (CustomArcadeScoreboard scoreboard : _scoreboard.values()) - { - Team team = scoreboard.getHandle().getTeam(player.getName()); - - if (team != null) - { - team.unregister(); - } - } - } - - /** - * Calls {@link #setupScoreboard(Player)} when the game switches to the prepare state. - */ - @EventHandler(priority = EventPriority.HIGHEST) - public void prepare(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Prepare) - { - return; - } - - for (Player player : Bukkit.getOnlinePlayers()) - { - setupScoreboard(player); - } - } - - /** - * Refreshes all player scoreboards upon an in progress state change. - */ - @EventHandler(priority = EventPriority.MONITOR) - public void live(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Prepare && event.GetState() != GameState.Live && event.GetState() != GameState.End) - { - return; - } - - refresh(); - } - - /** - * Calls the draw method every 10 ticks/0.5 seconds. - */ - @EventHandler - public void update(UpdateEvent event) - { - if (event.getType() != UpdateType.FAST) - { - return; - } - - for (CustomArcadeScoreboard scoreboard : _scoreboard.values()) - { - scoreboard.draw(); - } - } - - /** - * Updates the title animation of the scoreboard - */ - @EventHandler - public void updateTitle(UpdateEvent event) - { - if (event.getType() != UpdateType.FASTEST) - { - return; - } - - for (CustomArcadeScoreboard scoreboard : _scoreboard.values()) - { - scoreboard.updateTitle(); - } - } - - private void setupScoreboard(Player player) - { - UUID key = player.getUniqueId(); - CustomArcadeScoreboard scoreboard = _scoreboard.get(key); - - if (scoreboard == null) - { - scoreboard = new CustomArcadeScoreboard(player); - _scoreboard.put(player.getUniqueId(), scoreboard); - } - - player.setScoreboard(scoreboard.getHandle()); - } - - public CustomScoreboardModule setSidebar(BiConsumer consumer) - { - _scoreboardConsumer = consumer; - return this; - } - - public CustomScoreboardModule setPrefix(BiFunction function) - { - _prefixFunction = function; - return this; - } - - public CustomScoreboardModule setSuffix(BiFunction function) - { - _suffixFunction = function; - return this; - } - - public CustomScoreboardModule setTabList(BiFunction function) - { - _tabListFunction = function; - return this; - } - - public CustomScoreboardModule setUnderNameObjective(String name) - { - _underNameObjective = name; - return this; - } - - public CustomScoreboardModule setUnderName(BiFunction function) - { - _underNameFunction = function; - return this; - } - - public CustomScoreboardModule setNameTagVisibility(BiFunction function) - { - _nameTagVisibilityFunction = function; - return this; - } - - /** - * Refreshes all player's scoreboards. - */ - public void refresh() - { - for (CustomArcadeScoreboard scoreboard : _scoreboard.values()) - { - scoreboard.draw(false); - } - } - - /** - * Refreshes an individual player's scoreboard. - * - * @param perspective The player that has the perspective of the scoreboard to be refreshed. - */ - public void refreshAsPerspective(Player perspective) - { - CustomArcadeScoreboard scoreboard = _scoreboard.get(perspective.getUniqueId()); - - if (scoreboard == null) - { - return; - } - - scoreboard.draw(false); - } - - /** - * Refreshes all scoreboards but only where the subject of said scoreboard is the player passed in as the subject parameter. - */ - public void refreshAsSubject(Player subject) - { - for (CustomArcadeScoreboard scoreboard : _scoreboard.values()) - { - scoreboard.draw(subject); - } - } - - @Override - public void cleanup() - { - _scoreboard.clear(); - } - - /** - * An internal class that simply implements the actions set out by {@link CustomScoreboardModule}. - */ - class CustomArcadeScoreboard extends GameScoreboard - { - - CustomArcadeScoreboard(Player owner) - { - super(getGame(), owner); - } - - private void updateTag(Player subject) - { - Scoreboard handle = getHandle(); - String teamName = subject.getName(); - Team team = handle.getTeam(teamName); - - String prefix = _prefixFunction == null ? null : _prefixFunction.apply(getOwner(), subject); - String suffix = _suffixFunction == null ? null : _suffixFunction.apply(getOwner(), subject); - NameTagVisibility visibility = _nameTagVisibilityFunction == null ? null : _nameTagVisibilityFunction.apply(getOwner(), subject); - - if (team == null) - { - team = handle.registerNewTeam(teamName); - team.addEntry(subject.getName()); - } - - if (prefix != null) - { - if (team.getPrefix() == null || !team.getPrefix().equals(prefix)) - { - team.setPrefix(prefix); - } - } - if (suffix != null) - { - if (team.getSuffix() == null || !team.getSuffix().equals(suffix)) - { - team.setSuffix(suffix); - } - } - if (visibility != null) - { - if (!visibility.equals(team.getNameTagVisibility())) - { - team.setNameTagVisibility(visibility); - } - } - } - - private void updateTabList(Player subject) - { - if (_tabListFunction == null) - { - return; - } - - Scoreboard handle = getHandle(); - Objective objective = handle.getObjective(DisplaySlot.PLAYER_LIST); - int value = _tabListFunction.apply(getOwner(), subject); - - if (objective == null) - { - objective = handle.registerNewObjective("TabList", "dummy"); - objective.setDisplaySlot(DisplaySlot.PLAYER_LIST); - } - - Score score = objective.getScore(subject.getName()); - - if (score.getScore() != value) - { - score.setScore(value); - } - } - - private void updateUnderName(Player subject) - { - if (_underNameFunction == null || _underNameObjective == null) - { - return; - } - - Scoreboard handle = getHandle(); - Objective objective = handle.getObjective(DisplaySlot.BELOW_NAME); - int value = _underNameFunction.apply(getOwner(), subject); - - if (objective == null) - { - objective = handle.registerNewObjective(_underNameObjective, "dummy"); - objective.setDisplaySlot(DisplaySlot.BELOW_NAME); - } - - Score score = objective.getScore(subject.getName()); - - if (score.getScore() != value) - { - score.setScore(value); - } - } - - @Override - public void draw() - { - draw(true); - } - - public void draw(boolean sidebarOnly) - { - if (_scoreboardConsumer != null) - { - _scoreboardConsumer.accept(getOwner(), this); - } - if (!sidebarOnly) - { - for (Player player : Bukkit.getOnlinePlayers()) - { - draw(player); - } - } - super.draw(); - } - - private void draw(Player player) - { - updateTag(player); - updateTabList(player); - updateUnderName(player); - } - } - - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/CutCleanModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/CutCleanModule.java deleted file mode 100644 index 84e4f3a5..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/CutCleanModule.java +++ /dev/null @@ -1,107 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.event.EventHandler; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.Iterator; -import java.util.List; - -/* - * This module will implement CutClean-esque features within the game. - * - * In particular, the CutCleanModule#associateBlockDrop and CutCleanModule#associateMobDrop methods will - * allow you to drop different items for each block and mob killed - */ -public class CutCleanModule extends Module -{ - private final EnumMap> _blockDrops = new EnumMap<>(Material.class); - private final EnumMap> _mobDrops = new EnumMap<>(Material.class); - - /* - * Associates a material with a list of drops. - * - * Every time a block of that material is broken, the drops given will be dropped instead - * - * fixme does not support data ids - */ - public CutCleanModule associateBlockDrop(Material block, ItemStack... drops) - { - if (_blockDrops.containsKey(block)) - { - throw new IllegalStateException(block + " is already registered to " + _blockDrops.get(block)); - } - _blockDrops.put(block, new ArrayList<>(Arrays.asList(drops))); - return this; - } - - /* - * Associates a mob drop with a list of different drops - * - * Every time an item of the given type is dropped by a mob death, the alternative drops will be dropped instead - */ - public CutCleanModule associateMobDrop(Material drop, ItemStack... drops) - { - if (_mobDrops.containsKey(drop)) - { - throw new IllegalStateException(drop + " is already registered to " + _mobDrops.get(drop)); - } - _mobDrops.put(drop, new ArrayList<>(Arrays.asList(drops))); - return this; - } - - @EventHandler - public void on(BlockBreakEvent event) - { - List drops = _blockDrops.get(event.getBlock().getType()); - if (drops == null) - { - return; - } - - event.getBlock().setType(Material.AIR); - - getGame().getArcadeManager().getScheduler().runTaskLater(getGame().getArcadeManager().getPlugin(), () -> - { - Location dropLocation = event.getBlock().getLocation().add(0.5, 0.2, 0.5); - for (ItemStack drop : drops) - { - event.getBlock().getWorld().dropItem(dropLocation, drop.clone()); - } - }, 1L); - } - - @EventHandler - public void on(EntityDeathEvent event) - { - List drops = event.getDrops(); - List newDrops = new ArrayList<>(); - - Iterator itemIterator = drops.iterator(); - while (itemIterator.hasNext()) - { - ItemStack item = itemIterator.next(); - - List replacements = _mobDrops.get(item.getType()); - if (replacements == null) - { - continue; - } - - itemIterator.remove(); - - for (ItemStack replace : replacements) - { - newDrops.add(replace.clone()); - } - } - - drops.addAll(newDrops); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/EXPForKillsModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/EXPForKillsModule.java deleted file mode 100644 index 7374e6b0..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/EXPForKillsModule.java +++ /dev/null @@ -1,69 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; - -import mineplex.core.common.util.UtilPlayer; -import mineplex.minecraft.game.core.combat.CombatComponent; -import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; - -/** - * A legacy module that awards players enchanting levels when they kill or assist on killing another player. - */ -public class EXPForKillsModule extends Module -{ - - private final int _levelsForKill, _levelsForAssist; - - public EXPForKillsModule() - { - this(2, 1); - } - - public EXPForKillsModule(int levelsForKill, int levelsForAssist) - { - _levelsForKill = levelsForKill; - _levelsForAssist = levelsForAssist; - } - - @EventHandler - public void onCombatDeathEventLevels(CombatDeathEvent event) - { - if (!(event.GetEvent().getEntity() instanceof Player)) - { - return; - } - - Player killed = (Player) event.GetEvent().getEntity(); - - if (event.GetLog().GetKiller() != null) - { - Player killer = UtilPlayer.searchExact(event.GetLog().GetKiller().GetName()); - - if (killer != null && !killer.equals(killed)) - { - // Kill - killer.giveExpLevels(_levelsForKill); - killer.playSound(killer.getLocation(), Sound.LEVEL_UP, 1f, 1f); - } - } - - for (CombatComponent log : event.GetLog().GetAttackers()) - { - if (event.GetLog().GetKiller() != null && log.equals(event.GetLog().GetKiller())) - { - continue; - } - - Player assist = UtilPlayer.searchExact(log.GetName()); - - // Assist - if (assist != null) - { - assist.giveExpLevels(_levelsForAssist); - assist.playSound(assist.getLocation(), Sound.ORB_PICKUP, 1f, 1f); - } - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/EnderPearlModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/EnderPearlModule.java deleted file mode 100644 index 584e7aaa..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/EnderPearlModule.java +++ /dev/null @@ -1,151 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import java.util.HashMap; -import java.util.Map; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.EnderPearl; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.ProjectileHitEvent; -import org.bukkit.event.entity.ProjectileLaunchEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.UtilEvent; -import mineplex.core.common.util.UtilEvent.ActionType; -import mineplex.core.common.util.UtilParticle; -import mineplex.core.common.util.UtilParticle.ParticleType; -import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -public class EnderPearlModule extends Module -{ - - private static final int DEFAULT_COOLDOWN = 500; - - private final Map _pearls; - - private int _maxTicks = Integer.MAX_VALUE; - private long _cooldown = DEFAULT_COOLDOWN; - - public EnderPearlModule() - { - _pearls = new HashMap<>(); - } - - public EnderPearlModule setMaxTicks(int maxTicks) - { - _maxTicks = maxTicks; - return this; - } - - public EnderPearlModule setCooldown(long cooldown) - { - _cooldown = cooldown; - return this; - } - - @Override - public void cleanup() - { - _pearls.clear(); - } - - @EventHandler - public void interactEnderPearl(PlayerInteractEvent event) - { - if (!UtilEvent.isAction(event, ActionType.R) || !getGame().IsLive()) - { - return; - } - - Player player = event.getPlayer(); - ItemStack itemStack = player.getItemInHand(); - boolean inform = _cooldown > DEFAULT_COOLDOWN; - - if (itemStack != null && itemStack.getType() == Material.ENDER_PEARL && !Recharge.Instance.use(player, "Ender Pearl", _cooldown, inform, inform)) - { - event.setCancelled(true); - } - } - - @EventHandler - public void projectileLaunch(ProjectileLaunchEvent event) - { - Projectile entity = event.getEntity(); - - if (!getGame().IsLive() || !(entity instanceof EnderPearl) || !(entity.getShooter() instanceof Player)) - { - return; - } - - Player shooter = (Player) event.getEntity().getShooter(); - - _pearls.put(entity, shooter); - entity.setShooter(null); - } - - @EventHandler - public void update(UpdateEvent event) - { - if (event.getType() != UpdateType.TICK) - { - return; - } - - _pearls.entrySet().removeIf(entry -> - { - Projectile entity = entry.getKey(); - Player shooter = entry.getValue(); - - if (UtilPlayer.isSpectator(shooter)) - { - entity.remove(); - return true; - } - else if (entity.getTicksLived() > _maxTicks) - { - teleport(shooter, entity); - entity.remove(); - return true; - } - - UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, entity.getLocation(), 0, 0, 0, 0.1F, 3, ViewDist.LONG); - return false; - }); - } - - @EventHandler - public void projectileHit(ProjectileHitEvent event) - { - if (!(event.getEntity() instanceof EnderPearl)) - { - return; - } - - Projectile projectile = event.getEntity(); - Player shooter = _pearls.remove(projectile); - - if (shooter != null && getGame().isInsideMap(projectile.getLocation())) - { - teleport(shooter, projectile); - } - } - - private void teleport(Player shooter, Projectile entity) - { - Location toTeleport = entity.getLocation(); - Location playerLocation = shooter.getLocation(); - toTeleport.setYaw(playerLocation.getYaw()); - toTeleport.setPitch(playerLocation.getPitch()); - - shooter.teleport(toTeleport); - shooter.setFallDistance(0); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/GameStatisticsModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/GameStatisticsModule.java deleted file mode 100644 index 8f593f2c..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/GameStatisticsModule.java +++ /dev/null @@ -1,102 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.Managers; -import mineplex.core.common.util.UtilServer; -import mineplex.core.stats.event.StatChangeEvent; -import mineplex.core.stats.game.GameStatisticsManager; -import mineplex.core.stats.game.GameStats; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public class GameStatisticsModule extends Module -{ - - private static final GameStatisticsManager STATS_MANAGER; - - static - { - STATS_MANAGER = Managers.require(GameStatisticsManager.class); - } - - private GameStats _currentGame; - private final List _statsToListen; - private final Map _playerId; - - public GameStatisticsModule() - { - _statsToListen = new ArrayList<>(); - _playerId = new HashMap<>(); - } - - public void addStatListener(String stat) - { - _statsToListen.add(stat); - } - - @Override - protected void setup() - { - _currentGame = new GameStats(-1, UtilServer.getRegion(), getGame().GetType().getDisplay()); - } - - @Override - public void cleanup() - { - if (getGame().getArcadeManager().IsRewardStats() && _currentGame.isValid()) - { - STATS_MANAGER.saveGameStats(_currentGame); - } - } - - @EventHandler - public void live(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Live) - { - return; - } - - int id = 0; - for (Player player : getGame().GetPlayers(true)) - { - _playerId.put(player.getUniqueId(), ++id); - } - - STATS_MANAGER.getMapId(mapId -> _currentGame.setMapId(mapId), getGame().GetType().getDisplay(), getGame().WorldData.MapName); - _currentGame.setStartTime(System.currentTimeMillis()); - } - - @EventHandler - public void end(GameStateChangeEvent event) - { - if (event.GetState() != GameState.End) - { - return; - } - - _currentGame.setEndTime(System.currentTimeMillis()); - } - - @EventHandler - public void statChange(StatChangeEvent event) - { - Player player = event.getPlayer(); - String stat = event.getStatName(); - long change = event.getValueAfter() - event.getValueBefore(); - - if (_statsToListen.contains(getGame().GetName() + "." + stat) && _playerId.containsKey(player.getUniqueId())) - { - int playerId = _playerId.get(player.getUniqueId()); - _currentGame.getStats().putIfAbsent(playerId, new HashMap<>()); - _currentGame.getStats().get(playerId).put(stat, change); - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ItemGiverModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ItemGiverModule.java deleted file mode 100644 index 08130e94..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ItemGiverModule.java +++ /dev/null @@ -1,55 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.common.util.UtilInv; -import mineplex.core.common.util.UtilItem; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.List; - -/* - * This module will give all players specific items at the start of the game - */ -public class ItemGiverModule extends Module -{ - private final List _itemsToGive = new ArrayList<>(); - - public ItemGiverModule withItem(ItemStack item) - { - _itemsToGive.add(item.clone()); - return this; - } - - public ItemGiverModule withItems(ItemStack... items) - { - List clones = new ArrayList<>(); - for (ItemStack item : items) - { - clones.add(item.clone()); - } - - _itemsToGive.addAll(clones); - return this; - } - - - @EventHandler - public void on(GameStateChangeEvent event) - { - if(event.GetState() != Game.GameState.Live) - return; - - for (Player player : getGame().GetPlayers(true)) - { - for (ItemStack toGive : _itemsToGive) - { - UtilInv.insert(player, toGive.clone()); - } - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/MapCrumbleModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/MapCrumbleModule.java deleted file mode 100644 index f54ab50c..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/MapCrumbleModule.java +++ /dev/null @@ -1,208 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import java.util.HashSet; -import java.util.Set; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.scheduler.BukkitRunnable; - -import mineplex.core.common.util.MapUtil; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilTime; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -import nautilus.game.arcade.world.WorldData; - -public class MapCrumbleModule extends Module -{ - - private final Set _worldBlocks; - - private boolean _enabled; - private long _enableAfter; - private Runnable _onCrumble; - private int _rate = 4; - - public MapCrumbleModule() - { - _worldBlocks = new HashSet<>(100000); - } - - @Override - protected void setup() - { - WorldData worldData = getGame().WorldData; - - getGame().getArcadeManager().runSyncTimer(new BukkitRunnable() - { - int y = worldData.MinY; - - @Override - public void run() - { - if (!getGame().equals(getGame().getArcadeManager().GetGame())) - { - cancel(); - return; - } - - World world = worldData.World; - - for (int x = worldData.MinX; x < worldData.MaxX; x++) - { - for (int z = worldData.MinZ; z < worldData.MaxZ; z++) - { - Block block = world.getBlockAt(x, y, z); - - if (block.getType() != Material.AIR) - { - _worldBlocks.add(block); - } - } - } - - if (y++ == worldData.MaxY) - { - cancel(); - } - } - }, 1, 2); - } - - @Override - public void cleanup() - { - _worldBlocks.clear(); - } - - public MapCrumbleModule setEnabled(boolean enabled) - { - _enabled = enabled; - return this; - } - - public boolean isEnabled() - { - return _enabled; - } - - public MapCrumbleModule setEnableAfter(long enableAfter, Runnable onCrumble) - { - _enableAfter = enableAfter; - _onCrumble = onCrumble; - return this; - } - - public MapCrumbleModule setRate(int rate) - { - _rate = rate; - return this; - } - - public long getTimeUntilCrumble() - { - return getGame().GetStateTime() + _enableAfter - System.currentTimeMillis(); - } - - private void addWorldBlock(Block block) - { - if (block.getWorld().equals(getGame().WorldData.World)) - { - _worldBlocks.add(block); - } - } - - @EventHandler - public void crumbleStart(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC || !getGame().IsLive() || _enabled || !UtilTime.elapsed(getGame().GetStateTime(), _enableAfter)) - { - return; - } - - _enabled = true; - - if (_onCrumble != null) - { - _onCrumble.run(); - } - } - - @EventHandler - public void crumble(UpdateEvent event) - { - if (event.getType() != UpdateType.TICK || !getGame().IsLive() || _worldBlocks.isEmpty() || !_enabled) - { - return; - } - - Location center = getGame().GetSpectatorLocation(); - - for (int i = 0; i < _rate; i++) - { - Block bestBlock = null; - double bestDist = 0; - - for (Block block : _worldBlocks) - { - double dist = UtilMath.offset2dSquared(center, block.getLocation().add(0.5, 0, 0.5)); - - if (bestBlock == null || dist > bestDist) - { - bestBlock = block; - bestDist = dist; - } - } - - if (bestBlock == null) - { - continue; - } - - while (bestBlock.getRelative(BlockFace.DOWN).getType() != Material.AIR) - { - bestBlock = bestBlock.getRelative(BlockFace.DOWN); - } - - _worldBlocks.remove(bestBlock); - - if (!bestBlock.getWorld().equals(center.getWorld()) || bestBlock.getType() == Material.AIR) - { - continue; - } - - if (bestBlock.getType() == Material.WOODEN_DOOR || bestBlock.getType() == Material.IRON_DOOR_BLOCK) - { - MapUtil.QuickChangeBlockAt(bestBlock.getRelative(BlockFace.UP).getLocation(), Material.AIR); - } - else if (Math.random() > 0.95) - { - bestBlock.getWorld().spawnFallingBlock(bestBlock.getLocation().add(0.5, 0.5, 0.5), bestBlock.getType(), bestBlock.getData()); - } - - MapUtil.QuickChangeBlockAt(bestBlock.getLocation(), Material.AIR); - } - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void blockPlace(BlockPlaceEvent event) - { - addWorldBlock(event.getBlock()); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void blockPlace(BlockBreakEvent event) - { - _worldBlocks.remove(event.getBlock()); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/Module.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/Module.java deleted file mode 100644 index 62e73b4f..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/Module.java +++ /dev/null @@ -1,90 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import com.google.gson.JsonElement; -import nautilus.game.arcade.game.Game; -import org.bukkit.event.Listener; - -/** - * This is a Module - *

- * A Module represents something which will enhance or change the way games can be played. - * Modules should function independent of which specific gamemode is being played. - * If you need game-specific features, put it into that Game implementation or refactor it into a separate class (not a module). - *

- * Modules should never directly access other Modules via the Game instance. - * Instead, the game which requires cross-contamination should do so itself. - *

- * Modules should be associated per-game. Do not make them static - *

- * If your module is able to accept custom configuration, override the configure(JsonElement) method - * You can define the format of the json you wish to use. - * This custom configuration will be used to dynamically adjust gamemodes via Redis if needed - */ -public class Module implements Listener -{ - // The game this module belongs to - private Game _game; - - /** - * Initializes this module with the specific game instance. You should never do this as {@link Game} does it for you - */ - public final void initialize(Game game) - { - if (_game != null) - { - throw new IllegalArgumentException("Attempting to initialize module which has already been initialized for " + _game); - } - _game = game; - setup(); - } - - /** - * This method is called once initialization is complete. Do whatever you need to do with the {@link Game} here. - * - * All modules should have been configured before this method is called - */ - protected void setup() - { - - } - - /** - * If this module can be configured via a JsonObject/JsonPrimitive, then override this method - * to implement that feature - *

- * You can define how the JsonElement should be formatted. - *

- * It is recommended to have a "force" boolean which will reset this module to a clean state - * (to allow extensive customization using json) - */ - public void configure(JsonElement element) - { - - } - - /** - * This method is called once this module is no longer needed. - * This could be because the game is over - * Or because this module was unregistered - *

- * The {@link Game} will unregister this module as a listener for you. - * All you need to do is clean up after yourself - */ - public void cleanup() - { - - } - - /** - * Gets the game this module is associated with - */ - public Game getGame() - { - return _game; - } - - public final void register(Game instance) - { - instance.registerModule(this); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/OreVeinEditorModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/OreVeinEditorModule.java deleted file mode 100644 index 8bd58cc7..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/OreVeinEditorModule.java +++ /dev/null @@ -1,219 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.common.util.UtilBlock; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilWorld; -import mineplex.core.common.timing.TimingManager; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.BlockBreakEvent; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Predicate; - -/* - * This module will allow you to edit veins of ore live as players break them - */ -public class OreVeinEditorModule extends Module -{ - // Initial range to look for veins - // For example, if I break a block at 0,0,0 and RANGE is 3 - // Then this module will look for ores in the region of -3,-3,-3 to 3,3,3 - private static final int RANGE = 3; - - private boolean _debug = false; - private boolean _removeNonAirVeins = false; - - private Predicate _predicateIsOre = block -> - (block.getType() == Material.IRON_ORE || block.getType() == Material.GOLD_ORE || block.getType() == Material.DIAMOND_ORE); - - private Consumer> _consumerOreEditor = list -> - { - - }; - - public OreVeinEditorModule debug() - { - this._debug = true; - return this; - } - - public OreVeinEditorModule removeNonAirVeins() - { - this._removeNonAirVeins = true; - return this; - } - - public OreVeinEditorModule useFilter(Predicate filter) - { - this._predicateIsOre = filter; - return this; - } - - public OreVeinEditorModule useEditor(Consumer> editor) - { - this._consumerOreEditor = editor; - return this; - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void on(BlockBreakEvent event) - { - if (_debug) - TimingManager.start("Block Break"); - - // Find Nearby Ores - List ores = findOres(event.getBlock(), RANGE); - - // Anti-Xray - removeNonAirVeins(generateVeins(ores)); - - if (_debug) - TimingManager.stop("Block Break"); - } - - // Searches in a range x range x range cube for ores - private List findOres(Block source, int range) - { - List ores = new ArrayList<>(); - - for (int x = -range; x <= range; x++) - for (int z = -range; z <= range; z++) - for (int y = -range; y <= range; y++) - findOreFromBlock(ores, source.getRelative(x, y, z)); - - if (_debug) - for (Block debug : ores) - System.out.println("Found " + debug.getType() + " at " + UtilWorld.locToStrClean(debug.getLocation())); - - return ores; - } - - // Checks if the current block is ore - // If so, then search all blocks around it to see if they are ores - private void findOreFromBlock(List ores, Block block) - { - if (ores.contains(block)) - return; - - if (_predicateIsOre.test(block)) - { - ores.add(block); - - for (Block neighbour : UtilBlock.getSurrounding(block, true)) - { - findOreFromBlock(ores, neighbour); - } - } - } - - private List> generateVeins(List ores) - { - List> veins = new ArrayList<>(); - - while (!ores.isEmpty()) - { - Block block = ores.remove(0); - - if (_debug) - System.out.println("NEW VEIN - " + block.getType()); - - // Start New Vein - List vein = new ArrayList<>(); - veins.add(vein); - - vein.add(block); - - // Find Vein Ores - boolean addedToVein = true; - while (addedToVein) - { - addedToVein = false; - - Iterator oreIterator = ores.iterator(); - - while (oreIterator.hasNext()) - { - Block ore = oreIterator.next(); - - boolean inVein = false; - - // Check if in Vein - // fixme is this a good algorithm? - for (Block veinOre : vein) - { - if (UtilMath.offset(ore.getLocation(), veinOre.getLocation()) <= 2) - { - inVein = true; - break; - } - } - - // Add to Vein - if (inVein) - { - vein.add(ore); - oreIterator.remove(); - addedToVein = true; - } - } - } - - if (_debug) - for (Block veinOre : vein) - System.out.println(UtilWorld.locToStrClean(veinOre.getLocation())); - } - - return veins; - } - - private void removeNonAirVeins(List> oreVeins) - { - // Remove Non-Aired Veins - for (List vein : oreVeins) - { - boolean visible = false; - - // Check if Air is near Vein - outer: for (Block ore : vein) - { - for (Block visibleCheckBlock : UtilBlock.getSurrounding(ore, true)) - { - if (visibleCheckBlock.getType() == Material.AIR || UtilBlock.isVisible(visibleCheckBlock)) - { - visible = true; - break outer; - } - } - } - - if (visible) - _consumerOreEditor.accept(vein); - - // Remove Vein - if (!visible && _removeNonAirVeins) - { - if (_debug) - System.out.println("DELETING VEIN;"); - - for (Block ore : vein) - { - if (_debug) - System.out.println(ore.getType() + " " + UtilWorld.locToStrClean(ore.getLocation())); - - ore.setType(Material.STONE); - } - } - else - { - if (_debug) - System.out.println("VALID VEIN!"); - } - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/PlayerHeadModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/PlayerHeadModule.java deleted file mode 100644 index fee4bcf0..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/PlayerHeadModule.java +++ /dev/null @@ -1,169 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.inventory.PrepareItemCraftEvent; -import org.bukkit.event.player.PlayerItemConsumeEvent; -import org.bukkit.event.player.PlayerPickupItemEvent; -import org.bukkit.inventory.CraftingInventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.ShapedRecipe; -import org.bukkit.material.MaterialData; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.itemstack.ItemStackFactory; - -import nautilus.game.arcade.game.GameTeam; - -public class PlayerHeadModule extends Module -{ - private boolean _disableCraftingRegularApples = true; - private boolean _disableHeadPlace = true; - - @Override - protected void setup() - { - ShapedRecipe headApple2 = new ShapedRecipe(new ItemStack(Material.GOLDEN_APPLE, 1)); - headApple2.shape("GGG", "GHG", "GGG"); - headApple2.setIngredient('G', Material.GOLD_INGOT); - headApple2.setIngredient('H', new MaterialData(Material.SKULL_ITEM, (byte) 2)); - UtilServer.getServer().addRecipe(headApple2); - } - - public PlayerHeadModule enableCraftingRegularApples() - { - this._disableCraftingRegularApples = false; - return this; - } - - public PlayerHeadModule enableHeadPlace() - { - this._disableHeadPlace = false; - return this; - } - - @EventHandler - public void disableHeadPlace(BlockPlaceEvent event) - { - if ((event.getItemInHand().getType() == Material.SKULL || event.getItemInHand().getType() == Material.SKULL_ITEM) && - this._disableHeadPlace) - event.setCancelled(true); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void headPickup(PlayerPickupItemEvent event) - { - if (!getGame().IsLive()) - return; - - if (event.getItem().getItemStack().getType() == Material.SKULL_ITEM) - { - UtilPlayer.message(event.getPlayer(), " "); - UtilPlayer.message(event.getPlayer(), C.cGreen + C.Bold + "You picked up a Golden Head!"); - UtilPlayer.message(event.getPlayer(), C.cWhite + "Craft a Golden Head Apple with it for ultimate healing."); - UtilPlayer.message(event.getPlayer(), C.cWhite + "Use the recipe for Golden Apple, but Head replaces Apple."); - UtilPlayer.message(event.getPlayer(), " "); - } - } - - - @EventHandler - public void PlayerDeath(PlayerDeathEvent event) - { - Player player = event.getEntity(); - - GameTeam team = getGame().GetTeam(player); - if (team == null) - return; - - event.getDrops().add(getGoldenHead()); - } - - @EventHandler - public void eatHeadApple(PlayerItemConsumeEvent event) - { - if (event.getItem().getItemMeta().getDisplayName() == null) - return; - - if (!event.getItem().getItemMeta().getDisplayName().contains("Head")) - return; - - UtilPlayer.message(event.getPlayer(), "You ate " + event.getItem().getItemMeta().getDisplayName()); - - (new PotionEffect(PotionEffectType.ABSORPTION, 2400, 0)).apply(event.getPlayer()); - (new PotionEffect(PotionEffectType.REGENERATION, 200, 1)).apply(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.HIGH) - public void denyGoldApple(PrepareItemCraftEvent event) - { - if (event.getRecipe().getResult() == null) - return; - - Material type = event.getRecipe().getResult().getType(); - - if (type != Material.GOLDEN_APPLE) - return; - - CraftingInventory inv = event.getInventory(); - - for (ItemStack item : inv.getMatrix()) - if (item != null && item.getType() != Material.AIR) - if (item.getType() == Material.GOLD_INGOT) - return; - - inv.setResult(null); - } - - @EventHandler(priority = EventPriority.HIGH) - public void craftHeadApple(PrepareItemCraftEvent event) - { - if (event.getRecipe().getResult() == null) - return; - - Material type = event.getRecipe().getResult().getType(); - - if (type != Material.GOLDEN_APPLE) - return; - - CraftingInventory inv = event.getInventory(); - - for (ItemStack item : inv.getMatrix()) - if (item != null && item.getType() != Material.AIR) - if (item.getType() == Material.SKULL_ITEM || item.getType() == Material.SKULL) - { - if (item.getItemMeta() == null) - continue; - - if (item.getItemMeta().getDisplayName() == null) - continue; - - ItemStack apple = ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE, (byte) 0, 1, item - .getItemMeta().getDisplayName() + ChatColor.AQUA + " Golden Apple"); - apple.addUnsafeEnchantment(Enchantment.ARROW_DAMAGE, 1); - - inv.setResult(apple); - return; - } - } - - public static final ItemStack getGoldenHead() - { - return new ItemBuilder(Material.SKULL_ITEM) - .setData((short) 2) - .setAmount(1) - .setTitle(C.cGoldB + "Player Head") - .build(); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SafezoneModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SafezoneModule.java deleted file mode 100644 index 06259b75..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SafezoneModule.java +++ /dev/null @@ -1,236 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; -import net.minecraft.server.v1_8_R3.BlockPosition; -import net.minecraft.server.v1_8_R3.Entity; -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.IWorldAccess; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.event.EventHandler; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockGrowEvent; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPistonRetractEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.world.StructureGrowEvent; -import org.bukkit.event.world.WorldLoadEvent; - -import java.util.Iterator; -import java.util.function.Predicate; - -public class SafezoneModule extends Module -{ - private Predicate _isInSafezone = location -> true; - - public SafezoneModule filter(Predicate predicate) - { - this._isInSafezone = predicate; - return this; - } - - @Override - public void setup() - { - for (World world : Bukkit.getWorlds()) - { - registerWorldAccess(world); - } - } - - @EventHandler - public void onWorldLoad(WorldLoadEvent event) - { - registerWorldAccess(event.getWorld()); - } - - private void registerWorldAccess(World world) - { - IWorldAccess access = new IWorldAccess() - { - @Override - public void a(BlockPosition blockPosition) - { - Location location = new Location(world, blockPosition.getX(), blockPosition.getY(), blockPosition.getZ()); - if (isInSafeZone(location)) - { - Block block = location.getBlock(); - if (block.getType() == Material.COBBLESTONE || block.getType() == Material.OBSIDIAN || block.getType() == Material.STONE) - { - block.setType(Material.AIR); - } - } - } - - @Override - public void b(BlockPosition blockPosition) - { - - } - - @Override - public void a(int i, int i1, int i2, int i3, int i4, int i5) - { - - } - - @Override - public void a(String s, double v, double v1, double v2, float v3, float v4) - { - - } - - @Override - public void a(EntityHuman entityHuman, String s, double v, double v1, double v2, float v3, float v4) - { - - } - - @Override - public void a(int i, boolean b, double v, double v1, double v2, double v3, double v4, double v5, int... ints) - { - - } - - @Override - public void a(Entity entity) - { - - } - - @Override - public void b(Entity entity) - { - - } - - @Override - public void a(String s, BlockPosition blockPosition) - { - - } - - @Override - public void a(int i, BlockPosition blockPosition, int i1) - { - - } - - @Override - public void a(EntityHuman entityHuman, int i, BlockPosition blockPosition, int i1) - { - - } - - @Override - public void b(int i, BlockPosition blockPosition, int i1) - { - - } - }; - -// ((CraftWorld) world).getHandle().u.add(access); - } - - // fixme flowing water and stuff - - @EventHandler - public void preventBlockPlacement(BlockPlaceEvent event) - { - if (isInSafeZone(event.getBlock().getLocation())) - { - UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot build in this area!")); - event.setCancelled(true); - } - } - - @EventHandler - public void preventStructureGrow(StructureGrowEvent event) - { - Iterator blocks = event.getBlocks().iterator(); - while (blocks.hasNext()) - { - BlockState next = blocks.next(); - if (isInSafeZone(next.getLocation())) - { - blocks.remove(); - } - } - } - - @EventHandler - public void preventBlockGrow(BlockGrowEvent event) - { - if (isInSafeZone(event.getBlock().getLocation())) - { - event.setCancelled(true); - } - } - - @EventHandler - public void preventBoneMeal(PlayerInteractEvent event) - { - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) - { - boolean isIllegal = false; - if (!isIllegal) - { - isIllegal = event.getPlayer().getItemInHand().getType() == Material.INK_SACK && - event.getPlayer().getItemInHand().getData().getData() == (byte) 15; - } - - if (isIllegal && isInSafeZone(event.getClickedBlock().getLocation())) - { - event.setCancelled(true); - } - } - } - - @EventHandler - public void preventPistons(BlockPistonExtendEvent event) - { - boolean willBeUnsafe = false; - for (Block block : event.getBlocks()) - { - if (isInSafeZone(block.getRelative(event.getDirection()).getLocation())) - { - willBeUnsafe = true; - break; - } - } - if (willBeUnsafe) - { - event.setCancelled(true); - } - } - - @EventHandler - public void preventPistons(BlockPistonRetractEvent event) - { - boolean willBeUnsafe = false; - for (Block block : event.getBlocks()) - { - if (isInSafeZone(block.getLocation())) - { - willBeUnsafe = true; - break; - } - } - if (willBeUnsafe) - { - event.setCancelled(true); - } - } - - private boolean isInSafeZone(Location location) - { - return _isInSafezone.test(location); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SpawnRegenerationModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SpawnRegenerationModule.java deleted file mode 100644 index 1d8ff8ae..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SpawnRegenerationModule.java +++ /dev/null @@ -1,24 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; - -import mineplex.minecraft.game.core.condition.ConditionFactory; - -import nautilus.game.arcade.events.PlayerGameRespawnEvent; - -public class SpawnRegenerationModule extends Module -{ - - @EventHandler - public void respawn(PlayerGameRespawnEvent event) - { - Player player = event.GetPlayer(); - ConditionFactory factory = getGame().getArcadeManager().GetCondition().Factory(); - String reason = "Spawn Regeneration"; - - factory.Regen(reason, player, player, 5, 2, false, false, false); - factory.Protection(reason, player, player, 5, 2, false, false, false); - } - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SpawnShieldModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SpawnShieldModule.java deleted file mode 100644 index c8530338..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/SpawnShieldModule.java +++ /dev/null @@ -1,192 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.common.util.UtilAction; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilParticle; -import mineplex.core.common.util.UtilParticle.ParticleType; -import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.game.GameTeam; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Predicate; - -public class SpawnShieldModule extends Module -{ - - private final Set _shields; - - private int _damage = 5000; - private int _damageRadiusSquared = 25; - private int _velocityRadiusSquared = 9; - private boolean _displayParticles = true; - - public SpawnShieldModule() - { - _shields = new HashSet<>(); - } - - public SpawnShieldModule registerShield(GameTeam team, List barriers) - { - return registerShield(team::HasPlayer, barriers, UtilAlg.getAverageLocation(team.GetSpawns())); - } - - public SpawnShieldModule registerShield(Predicate shouldNotAffect, List barriers, Location center) - { - _shields.add(new Shield(shouldNotAffect, barriers, center)); - return this; - } - - public SpawnShieldModule setDamage(int damage) - { - _damage = damage; - return this; - } - - public SpawnShieldModule setDamageRadius(int radius) - { - _damageRadiusSquared = radius * radius; - return this; - } - - public SpawnShieldModule setVelocityRadius(int radius) - { - _velocityRadiusSquared = radius * radius; - return this; - } - - public SpawnShieldModule setDisplayParticles(boolean display) - { - _displayParticles = display; - return this; - } - - @Override - public void setup() - { - for (Shield shield : _shields) - { - for (Location location : shield.Barriers) - { - location.getBlock().setType(Material.AIR); - } - } - } - - @EventHandler - public void updateShield(UpdateEvent event) - { - if (event.getType() != UpdateType.FASTER) - { - return; - } - - for (Shield shield : _shields) - { - for (Player player : getGame().GetPlayers(true)) - { - if (UtilPlayer.isSpectator(player) || shield.ShouldNotAffect.test(player)) - { - continue; - } - - if (UtilMath.offsetSquared(player.getLocation(), shield.Center) < _damageRadiusSquared) - { - getGame().Manager.GetDamage().NewDamageEvent(player, null, null, DamageCause.VOID, _damage, false, true, true, getGame().GetName(), "Spawn Shield"); - } - else - { - for (Location location : shield.Barriers) - { - if (UtilMath.offsetSquared(player.getLocation(), location) < _velocityRadiusSquared) - { - Entity passenger = player.getPassenger(); - - UtilAction.velocity(passenger == null ? player : passenger, UtilAlg.getTrajectory(location, player.getLocation()).setY(0.4)); - break; - } - } - } - } - } - } - - @EventHandler - public void updateParticles(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC || !_displayParticles) - { - return; - } - - for (Shield shield : _shields) - { - for (Player player : getGame().GetPlayers(true)) - { - if (UtilPlayer.isSpectator(player) || shield.ShouldNotAffect.test(player)) - { - continue; - } - - for (Location location : shield.Barriers) - { - UtilParticle.PlayParticle(ParticleType.BARRIER, location.clone().add(0, 0.5, 0), 0, 0, 0, 0.1F, 1, ViewDist.SHORT, player); - } - } - } - } - - @Override - public void cleanup() - { - _shields.clear(); - } - - @EventHandler - public void onCustomDamage(CustomDamageEvent event) - { - Player player = event.GetDamageePlayer(); - - if (player == null) - { - return; - } - - for (Shield shield : _shields) - { - if (shield.ShouldNotAffect.test(player) && UtilMath.offsetSquared(player.getLocation(), shield.Center) < _damageRadiusSquared) - { - event.SetCancelled("Spawn Shield"); - return; - } - } - } - - private class Shield - { - - Predicate ShouldNotAffect; - List Barriers; - Location Center; - - Shield(Predicate shouldNotAffect, List barriers, Location center) - { - ShouldNotAffect = shouldNotAffect; - Barriers = barriers; - Center = center; - } - } - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/StrikeGamesModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/StrikeGamesModule.java deleted file mode 100644 index a398eba4..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/StrikeGamesModule.java +++ /dev/null @@ -1,220 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.common.util.UtilItem; -import nautilus.game.arcade.game.games.minestrike.GunModule; -import nautilus.game.arcade.game.games.minestrike.items.grenades.FlashBang; -import nautilus.game.arcade.game.games.minestrike.items.grenades.Grenade; -import nautilus.game.arcade.game.games.minestrike.items.grenades.HighExplosive; -import nautilus.game.arcade.game.games.minestrike.items.grenades.Incendiary; -import nautilus.game.arcade.game.games.minestrike.items.grenades.Molotov; -import nautilus.game.arcade.game.games.minestrike.items.grenades.Smoke; -import nautilus.game.arcade.game.games.minestrike.items.guns.Gun; -import nautilus.game.arcade.game.games.minestrike.items.guns.GunStats; -import nautilus.game.arcade.game.games.minestrike.items.guns.GunType; -import nautilus.game.arcade.game.games.minestrike.items.guns.Shotgun; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.enchantment.EnchantItemEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerItemConsumeEvent; -import org.bukkit.event.player.PlayerPickupItemEvent; -import org.bukkit.event.player.PlayerToggleSneakEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.HashMap; -import java.util.Map; - -public class StrikeGamesModule extends Module -{ - - private final Map _helmets; - private final GunModule _gunModule; - - public StrikeGamesModule(GunModule gunModule) - { - _gunModule = gunModule; - _helmets = new HashMap<>(); - } - - @EventHandler - public void eatingGrenades(PlayerItemConsumeEvent event) - { - Material material = event.getItem().getType(); - - switch (material) - { - case POTATO_ITEM: - case CARROT_ITEM: - case APPLE: - case PORK: - case GRILLED_PORK: - event.setCancelled(true); - break; - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void addHelmet(PlayerToggleSneakEvent event) - { - Player player = event.getPlayer(); - ItemStack helmet = player.getInventory().getHelmet(); - - if (!getGame().IsLive() || !getGame().IsAlive(player) || _gunModule.getScoped().containsKey(player) || helmet == null) - { - return; - } - - _helmets.put(event.getPlayer(), helmet); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void pumpkinDrop(PlayerDeathEvent event) - { - Player player = event.getEntity(); - - event.getDrops().removeIf(item -> item.getType() == Material.PUMPKIN || item.getType() == Material.PUMPKIN_STEM); - - if (_helmets.containsKey(player)) - { - event.getDrops().add(_helmets.get(player)); - } - } - - @EventHandler - public void weaponEnchantment(EnchantItemEvent event) - { - if (!UtilItem.isArmor(event.getItem())) - { - event.setCancelled(true); - } - } - - @EventHandler - public void addEquipment(InventoryClickEvent event) - { - if (event.getCurrentItem() == null || !(event.getWhoClicked() instanceof Player) || event.getClickedInventory() instanceof PlayerInventory) - { - return; - } - - Player player = (Player) event.getWhoClicked(); - ItemStack stack = event.getCurrentItem(); - for (GunStats stat : GunStats.values()) - { - if (stat.getSkin() == stack.getType()) - { - Gun gun; - if (stat.getGunType() == GunType.SHOTGUN) - { - gun = new Shotgun(stat, _gunModule); - } - else - { - gun = new Gun(stat, _gunModule); - } - gun.setStack(stack); - gun.updateWeaponName(player, null, false); - gun.addID(); - _gunModule.registerGun(gun, player); - return; - } - } - - Grenade grenade = null; - - switch (stack.getType()) - { - case APPLE: - grenade = new HighExplosive(); - break; - case CARROT_ITEM: - grenade = new FlashBang(); - break; - case POTATO_ITEM: - grenade = new Smoke(); - break; - case PORK: - grenade = new Incendiary(); - break; - case GRILLED_PORK: - grenade = new Molotov(); - break; - } - - if (grenade == null) - { - return; - } - - ItemMeta meta = stack.getItemMeta(); - meta.setDisplayName(grenade.getName()); - stack.setItemMeta(meta); - grenade.setStack(stack); - _gunModule.registerGrenade(grenade, player); - } - - @EventHandler - public void triggerPickup(PlayerPickupItemEvent event) - { - if (!getGame().InProgress() || !getGame().IsAlive(event.getPlayer())) - { - return; - } - - //Guns - Gun gun = _gunModule.getDroppedGuns().get(event.getItem()); - if (gun != null) - { - _gunModule.deregisterDroppedGun(gun); - _gunModule.registerGun(gun, event.getPlayer()); - gun.setStack(event.getItem().getItemStack()); - } - - //Grenades - Grenade grenade = _gunModule.getDroppedGrenades().get(event.getItem()); - if (grenade != null) - { - _gunModule.deregisterDroppedGrenade(grenade); - _gunModule.registerGrenade(grenade, event.getPlayer()); - grenade.setStack(event.getItem().getItemStack()); - } - } - - @EventHandler - public void triggerDrop(PlayerDropItemEvent event) - { - if (!getGame().InProgress()) - { - return; - } - - Player player = event.getPlayer(); - ItemStack itemStack = event.getItemDrop().getItemStack(); - - //Guns - Gun gun = _gunModule.getGunInHand(player, itemStack); - - if (gun != null) - { - gun.drop(_gunModule, player, false, false); - event.getItemDrop().remove(); - player.setItemInHand(null); - return; - } - - //Grenades - Grenade grenade = _gunModule.getGrenadeInHand(player, itemStack); - if (grenade != null) - { - grenade.drop(_gunModule, player, false, false); - event.getItemDrop().remove(); - player.setItemInHand(null); - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/TeamArmorModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/TeamArmorModule.java deleted file mode 100644 index 14c77260..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/TeamArmorModule.java +++ /dev/null @@ -1,156 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import java.util.HashSet; -import java.util.Set; - -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEvent; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilEvent; -import mineplex.core.common.util.UtilInv; -import mineplex.core.common.util.UtilItem; -import mineplex.core.itemstack.ItemBuilder; - -import nautilus.game.arcade.events.PlayerKitGiveEvent; -import nautilus.game.arcade.game.GameTeam; - -/** - * This module handles setting armor for team games such as Micro Battles. It allows you to set the player's armor - * to be the team's color. It also allows you to add an chestplate to players' hotbar representing their team. - * - * These events are listening at MONITOR because they (should) be strict enough that it should not be possible to - * interfere with any other listeners - */ -public class TeamArmorModule extends Module -{ - private boolean _giveTeamArmor = false; - private boolean _giveHotbarItem = false; - - private Set _hotbarNames = new HashSet<>(); - private Set _armorNames = new HashSet<>(); - - public TeamArmorModule giveTeamArmor() - { - _giveTeamArmor = true; - return this; - } - - public TeamArmorModule giveHotbarItem() - { - _giveHotbarItem = true; - return this; - } - - public TeamArmorModule dontGiveTeamArmor() - { - _giveTeamArmor = false; - return this; - } - - public TeamArmorModule dontGiveHotbarItem() - { - _giveHotbarItem = false; - return this; - } - - @EventHandler - public void giveArmor(PlayerKitGiveEvent event) - { - apply(event.getPlayer()); - } - - public void apply(Player player) - { - GameTeam gameTeam = getGame().GetTeam(player); - if (gameTeam == null) - return; - - Color color = gameTeam.GetColorBase(); - - if (_giveTeamArmor) - { - String itemName = gameTeam.GetColor() + C.Bold + "Team Armor"; - _armorNames.add(itemName); - player.getInventory().setHelmet(new ItemBuilder(Material.LEATHER_HELMET).setColor(color).setTitle(itemName).setUnbreakable(true).build()); - player.getInventory().setChestplate(new ItemBuilder(Material.LEATHER_CHESTPLATE).setColor(color).setTitle(itemName).setUnbreakable(true).build()); - player.getInventory().setLeggings(new ItemBuilder(Material.LEATHER_LEGGINGS).setColor(color).setTitle(itemName).setUnbreakable(true).build()); - player.getInventory().setBoots(new ItemBuilder(Material.LEATHER_BOOTS).setColor(color).setTitle(itemName).setUnbreakable(true).build()); - } - - if (_giveHotbarItem && getGame().InProgress()) - { - String teamName = gameTeam.GetFormattedName(); - _hotbarNames.add(teamName); - player.getInventory().setItem(8, new ItemBuilder(Material.LEATHER_CHESTPLATE).setColor(color).setTitle(teamName).setUnbreakable(true).build()); - } - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void disallowDrop(PlayerDropItemEvent event) - { - if (!_giveTeamArmor && !_giveHotbarItem) - return; - - if (!_hotbarNames.contains(UtilItem.getDisplayName(event.getItemDrop().getItemStack()))) - return; - - event.setCancelled(true); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void disallowEquip(PlayerInteractEvent event) - { - if (!_giveHotbarItem) - return; - - if (!UtilEvent.isAction(event, UtilEvent.ActionType.R)) - return; - - if (!_hotbarNames.contains(UtilItem.getDisplayName(event.getItem()))) - return; - - event.setCancelled(true); - - getGame().getArcadeManager().runSyncLater(() -> - { - event.getPlayer().updateInventory(); - }, 1L); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void disallowMoveHotbar(InventoryClickEvent event) - { - if (!_giveHotbarItem) - return; - - if (!getGame().InProgress()) - return; - - if (!UtilInv.shouldCancelEvent(event, item -> _hotbarNames.contains(UtilItem.getDisplayName(item)))) - return; - - event.setCancelled(true); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void disallowMoveArmor(InventoryClickEvent event) - { - if (!_giveTeamArmor) - return; - - if (!getGame().InProgress()) - return; - - if (!UtilInv.shouldCancelEvent(event, item -> _armorNames.contains(UtilItem.getDisplayName(item)))) - return; - - event.setCancelled(true); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ThrowableTNTModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ThrowableTNTModule.java deleted file mode 100644 index a10b1adc..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/ThrowableTNTModule.java +++ /dev/null @@ -1,133 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import java.util.HashMap; -import java.util.Map; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.event.EventHandler; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.ExplosionPrimeEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilAction; -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.UtilPlayer; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.mission.MissionTrackerType; -import mineplex.core.recharge.Recharge; - -public class ThrowableTNTModule extends Module -{ - - private static final int EXPLOSION_RADIUS = 14; - - private final Map _throwers; - - private ItemStack _tntItem; - private int _fuseTicks = 60; - private boolean _throwAndDrop; - private double _throwStrength = 1.3; - - public ThrowableTNTModule() - { - _throwers = new HashMap<>(); - } - - @Override - protected void setup() - { - ItemBuilder builder = new ItemBuilder(Material.TNT); - - if (_throwAndDrop) - { - builder.setTitle(C.cYellowB + "Left Click - Throw" + C.cWhite + " / " + C.cYellowB + "Right Click - Drop"); - } - else - { - builder.setTitle(C.cYellow + "Throwable TNT"); - } - - _tntItem = builder.build(); - } - - public ThrowableTNTModule setFuseTicks(int fuseTicks) - { - _fuseTicks = fuseTicks; - return this; - } - - public ThrowableTNTModule setThrowAndDrop(boolean throwAndDrop) - { - _throwAndDrop = throwAndDrop; - return this; - } - - public ThrowableTNTModule setThrowStrength(double throwStrength) - { - _throwStrength = throwStrength; - return this; - } - - public ItemStack getTntItem() - { - return _tntItem; - } - - @EventHandler - public void playerThrowTNT(PlayerInteractEvent event) - { - if (event.getAction() == Action.PHYSICAL || !getGame().IsLive()) - { - return; - } - - Player player = event.getPlayer(); - ItemStack itemStack = player.getItemInHand(); - - if (UtilPlayer.isSpectator(player) || itemStack == null || itemStack.getType() != Material.TNT || UtilBlock.usable(event.getClickedBlock()) || !Recharge.Instance.use(player, "Throw TNT", 500, false, true)) - { - return; - } - - player.setItemInHand(UtilInv.decrement(itemStack)); - event.setCancelled(true); - - Location location = player.getEyeLocation(); - location.add(location.getDirection()); - - TNTPrimed tntPrimed = location.getWorld().spawn(location, TNTPrimed.class); - tntPrimed.setFuseTicks(_fuseTicks); - - if (!_throwAndDrop || UtilEvent.isAction(event, ActionType.L)) - { - UtilAction.velocity(tntPrimed, location.getDirection(), _throwStrength, false, 0, 0.3, 1, false); - } - - _throwers.put(tntPrimed, player); - getGame().getArcadeManager().getMissionsManager().incrementProgress(player, 1, MissionTrackerType.GAME_THROW_TNT, getGame().GetType().getDisplay(), null); - } - - @EventHandler - public void onExplosionPrime(ExplosionPrimeEvent event) - { - Entity entity = event.getEntity(); - Player player = _throwers.get(entity); - - if (player != null) - { - for (Player other : UtilPlayer.getNearby(entity.getLocation(), EXPLOSION_RADIUS)) - { - getGame().getArcadeManager().GetCondition().Factory().Explosion("Throwable TNT", other, player, 50, 0.1, false, false); - } - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/TrainingGameModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/TrainingGameModule.java deleted file mode 100644 index e2cb5f95..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/TrainingGameModule.java +++ /dev/null @@ -1,262 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Function; -import java.util.function.Predicate; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.events.EntityVelocityChangeEvent; -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; - -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.kit.Kit; - -public class TrainingGameModule extends Module -{ - - private static final String RETURN_TO_SPAWN_RECHARGE = "Return To Select A Kit"; - private static final int RETURN_TO_SPAWN_COOLDOWN = 8000; - private static final ItemStack RETURN_TO_SPAWN_ITEM = new ItemBuilder(Material.BED) - .setTitle(C.cGreenB + RETURN_TO_SPAWN_RECHARGE) - .addLore("Click to return to the spawn island", "where you can select a new kit.") - .build(); - - private Function _teamFunction; - private Predicate _skillFunction; - private Predicate _damageFunction; - private Predicate _kitSelectFunction; - private boolean _giveReturnToSpawn = true; - - @EventHandler - public void live(GameStateChangeEvent event) - { - if (event.GetState() != Game.GameState.Live) - { - return; - } - - List locations = getGame().WorldData.GetDataLocs("PURPLE"); - int i = 0; - - if (locations.isEmpty()) - { - return; - } - - for (Kit kit : getGame().GetKits()) - { - Location location = locations.get(i++); - kit.getGameKit().createNPC(location); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - public void playerLogin(PlayerLoginEvent event) - { - Player player = event.getPlayer(); - Game game = getGame(); - GameTeam team = _teamFunction == null ? game.GetTeamList().get(0) : _teamFunction.apply(player); - - team.AddPlayer(player, true); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void playerJoin(PlayerJoinEvent event) - { - if (!getGame().InProgress()) - { - return; - } - - Player player = event.getPlayer(); - - if (UtilPlayer.isSpectator(player)) - { - return; - } - - GameTeam team = getGame().GetTeam(player); - - team.SpawnTeleport(player); - } - - - @EventHandler(priority = EventPriority.LOWEST) - public void playerInteract(PlayerInteractEvent event) - { - if (_skillFunction == null) - { - return; - } - - Player player = event.getPlayer(); - - if (!_skillFunction.test(player)) - { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - public void playerInteract(EntityDamageEvent event) - { - if (_skillFunction == null || !(event.getEntity() instanceof Player)) - { - return; - } - - Player player = (Player) event.getEntity(); - - if (!_skillFunction.test(player)) - { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void entityDamage(CustomDamageEvent event) - { - if (!(event.GetDamageeEntity() instanceof Player)) - { - return; - } - - Player player = event.GetDamageePlayer(); - - if (!event.isCancelled()) - { - Recharge.Instance.useForce(player, RETURN_TO_SPAWN_RECHARGE, RETURN_TO_SPAWN_COOLDOWN); - - if (event.GetDamagerEntity(true) instanceof Player) - { - Recharge.Instance.useForce(event.GetDamagerPlayer(true), RETURN_TO_SPAWN_RECHARGE, RETURN_TO_SPAWN_COOLDOWN); - } - } - - if (_damageFunction != null && !_damageFunction.test(player)) - { - event.SetCancelled("Training Area"); - } - } - - @EventHandler - public void entityVelocity(EntityVelocityChangeEvent event) - { - Entity entity = event.getEntity(); - - if (!(entity instanceof Player)) - { - return; - } - - Player player = (Player) entity; - - if (!_damageFunction.test(player)) - { - event.setCancelled(true); - } - } - - @EventHandler - public void giveReturnToSpawn(UpdateEvent event) - { - if (event.getType() != UpdateType.FAST || !_giveReturnToSpawn) - { - return; - } - - for (Player player : getGame().GetPlayers(true)) - { - if (player.getInventory().contains(RETURN_TO_SPAWN_ITEM)) - { - continue; - } - - player.getInventory().setItem(8, RETURN_TO_SPAWN_ITEM); - } - } - - @EventHandler - public void interactReturnToSpawn(PlayerInteractEvent event) - { - Player player = event.getPlayer(); - ItemStack itemStack = player.getItemInHand(); - - if (itemStack == null || !itemStack.isSimilar(RETURN_TO_SPAWN_ITEM)) - { - return; - } - - if (event.isCancelled()) - { - player.sendMessage(F.main("Game", "You are already at the " + F.greenElem("Kit Selection Island") + ".")); - return; - } - - if (Recharge.Instance.usable(player, RETURN_TO_SPAWN_RECHARGE)) - { - getGame().RespawnPlayer(player); - } - else - { - player.sendMessage(F.main("Game", "You can't return to the " + F.greenElem("Kit Selection Island") + " if you are in " + F.greenElem("PVP") + ".")); - } - } - - public void preventReturnToSpawn(Player player) - { - Recharge.Instance.useForce(player, RETURN_TO_SPAWN_RECHARGE, RETURN_TO_SPAWN_COOLDOWN); - } - - public TrainingGameModule setTeamFunction(Function function) - { - _teamFunction = function; - return this; - } - - public TrainingGameModule setSkillFunction(Predicate function) - { - _skillFunction = function; - return this; - } - - public TrainingGameModule setDamageFunction(Predicate function) - { - _damageFunction = function; - return this; - } - - public TrainingGameModule setKitSelectFunction(Predicate function) - { - _kitSelectFunction = function; - return this; - } - - public TrainingGameModule setGiveReturnToSpawn(boolean b) - { - _giveReturnToSpawn = b; - return this; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/VersionModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/VersionModule.java deleted file mode 100644 index b1bfd75a..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/VersionModule.java +++ /dev/null @@ -1,46 +0,0 @@ -package nautilus.game.arcade.game.modules; - -import mineplex.core.common.MinecraftVersion; -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.portal.GenericServer; -import mineplex.core.portal.Intent; -import mineplex.core.portal.Portal; -import org.bukkit.entity.Player; - -/** - * This module functions as a checkpoint for any client connecting a game - * server. Making sure they have the minimum client version for your game. - * - * @see MinecraftVersion - */ -public class VersionModule extends Module -{ - private final MinecraftVersion _minecraftVersion; - - public VersionModule(MinecraftVersion minecraftVersion) - { - _minecraftVersion = minecraftVersion; - - for (Player player : UtilServer.getPlayers()) - { - if (UtilPlayer.getVersion(player) != _minecraftVersion) - { - UtilPlayer.message(player, C.cGold + C.Bold + "Please use Minecraft " + _minecraftVersion.friendlyName() + " or newer to play this game!"); - Portal.getInstance().sendPlayerToGenericServer(player, GenericServer.HUB, Intent.KICK); - } - } - } - /* - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event) - { - if (MinecraftVersion.fromInt(event.spigot().getVersion()) != _minecraftVersion) - { - event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, C.cGold + C.Bold + "Please use Minecraft " + _minecraftVersion.friendlyName() + " or newer to play this game!"); - } - } - - */ -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/antixray/AntiXrayModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/antixray/AntiXrayModule.java deleted file mode 100644 index 3c3caf09..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/antixray/AntiXrayModule.java +++ /dev/null @@ -1,145 +0,0 @@ -package nautilus.game.arcade.game.modules.antixray; - -import mineplex.core.common.util.UtilServer; -import nautilus.game.arcade.game.modules.Module; -import org.bukkit.Material; -import org.bukkit.plugin.RegisteredServiceProvider; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -/* - * This module will enable antixray for this specific game - * - * NOTE: The game server must also have the Mineplex Orebfuscator plugin installed - */ -public class AntiXrayModule extends Module -{ - private AntiXrayService _service; - - @Override - protected void setup() - { - RegisteredServiceProvider rsp = UtilServer.getServer().getServicesManager().getRegistration(AntiXrayService.class); - if (rsp == null) - { - getGame().unregisterModule(this); - System.out.println("!!!ERROR!!! AntiXray module was registered but the Mineplex Orebfuscator Service was not registered"); - return; - } - AntiXrayService service = rsp.getProvider(); - if (service == null) - { - getGame().unregisterModule(this); - System.out.println("!!!ERROR!!! AntiXray module was registered but the Mineplex Orebfuscator Service was null"); - return; - } - _service = service; - } - - @Override - public void cleanup() - { - _service.setEnabled(false); - _service.clearCache(); - } - - public AntiXrayModule setEnabled(boolean enabled) - { - _service.setEnabled(enabled); - return this; - } - - public AntiXrayModule setUpdateOnDamage(boolean updateOnDamage) - { - _service.setUpdateOnDamage(updateOnDamage); - return this; - } - - public AntiXrayModule setEngineMode(int engineMode) - { - _service.setEngineMode(engineMode); - return this; - } - - public AntiXrayModule setInitialRadius(int initialRadius) - { - _service.setInitialRadius(initialRadius); - return this; - } - - public AntiXrayModule setUpdateRadius(int updateRadius) - { - _service.setUpdateRadius(updateRadius); - return this; - } - - public AntiXrayModule setUseProximityHider(boolean useProximityHider) - { - _service.setUseProximityHider(useProximityHider); - return this; - } - - public AntiXrayModule setAntiTexturePacksAndFreecam(boolean antiTexturePacksAndFreecam) - { - _service.setAntiTexturePacksAndFreecam(antiTexturePacksAndFreecam); - return this; - } - - public AntiXrayModule setDarknessHideBlocks(boolean darknessHideBlocks) - { - _service.setDarknessHideBlocks(darknessHideBlocks); - return this; - } - - public AntiXrayModule setObfuscateBlocks(Material... materials) - { - return setObfuscateBlocks(Arrays.asList(materials)); - } - - public AntiXrayModule setObfuscateBlocks(List materials) - { - _service.setObfuscateBlocks(materials); - return this; - } - - public AntiXrayModule setRandomBlocks(Material... materials) - { - return setRandomBlocks(Arrays.asList(materials)); - } - - public AntiXrayModule setRandomBlocks(List materials) - { - _service.setRandomBlocks(materials); - return this; - } - - public AntiXrayModule setProximityBlocks(Material... materials) - { - return setProximityBlocks(Arrays.asList(materials)); - } - - public AntiXrayModule setProximityBlocks(List materials) - { - _service.setProximityBlocks(materials); - return this; - } - public AntiXrayModule setDarknessBlocks(Material... materials) - { - return setDarknessBlocks(Arrays.asList(materials)); - } - - public AntiXrayModule setDarknessBlocks(List materials) - { - _service.setDarknessBlocks(materials); - return this; - } - - public AntiXrayModule setUseCache(boolean useCache) - { - _service.setUseCache(true); - return this; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/antixray/AntiXrayService.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/antixray/AntiXrayService.java deleted file mode 100644 index d84ff27c..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/antixray/AntiXrayService.java +++ /dev/null @@ -1,57 +0,0 @@ -package nautilus.game.arcade.game.modules.antixray; - -import org.bukkit.Material; - -import java.util.Arrays; -import java.util.List; - -public interface AntiXrayService -{ - void setEnabled(boolean enabled); - - void setUpdateOnDamage(boolean updateOnDamage); - - void setEngineMode(int engineMode); - - void setInitialRadius(int initialRadius); - - void setUpdateRadius(int updateRadius); - - void setUseWorldsAsBlacklist(boolean useWorldsAsBlacklist); - - void setUseCache(boolean useCache); - - void setMaxLoadedCacheFiles(int maxLoadedCacheFiles); - - void clearCache(); - - void setProximityHiderRate(int proximityHiderRate); - - void setProximityHiderDistance(int proximityHiderDistance); - - void setProximityHiderId(int proximityHiderId); - - void setProximityHiderEnd(int proximityHiderEnd); - - void setUseSpecialBlockForProximityHider(boolean useSpecialBlockForProximityHider); - - void setUseYLocationProximity(boolean useYLocationProximity); - - void setAirGeneratorMaxChance(int airGeneratorMaxChance); - - void setWorlds(List worlds); - - void setUseProximityHider(boolean useProximityHider); - - void setAntiTexturePacksAndFreecam(boolean antiTexturePacksAndFreecam); - - void setDarknessHideBlocks(boolean darknessHideBlocks); - - void setObfuscateBlocks(List materials); - - void setRandomBlocks(List materials); - - void setDarknessBlocks(List materials); - - void setProximityBlocks(List materials); -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePoint.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePoint.java deleted file mode 100644 index 8380b203..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePoint.java +++ /dev/null @@ -1,334 +0,0 @@ -package nautilus.game.arcade.game.modules.capturepoint; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; - -import org.bukkit.ChatColor; -import org.bukkit.Effect; -import org.bukkit.FireworkEffect.Type; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Player; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilBlock; -import mineplex.core.common.util.UtilFirework; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilTime; - -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.GameTeam; - -public class CapturePoint -{ - - static final int MAX_RADIUS = 5; - private static final int MAX_PROGRESS = 5; - private static final int MAX_PROGRESS_NEUTRAL = 10; - private static final int MIN_INFORM_TIME = (int) TimeUnit.SECONDS.toMillis(30); - - private final Game _host; - - private final String _name; - private final ChatColor _colour; - - private final Location _center; - private final List _wool; - private final List _changed; - - private final double _captureDist; - - private GameTeam _owner; - private GameTeam _side; - private int _progress; - private long _lastInform; - - CapturePoint(Game host, String name, ChatColor colour, Location center) - { - _host = host; - _name = name; - _colour = colour; - _center = center; - _wool = new ArrayList<>(36); - _changed = new ArrayList<>(_wool.size()); - - double highestDist = 0; - - for (Entry entry : UtilBlock.getInRadius(center, MAX_RADIUS).entrySet()) - { - Block block = entry.getKey(); - double offset = entry.getValue(); - - if (block.getType() != Material.WOOL) - { - continue; - } - - if (offset > highestDist) - { - highestDist = offset; - } - - _wool.add(block); - } - Collections.shuffle(_wool); - - _captureDist = Math.pow(highestDist * (double) MAX_RADIUS + 0.5D, 2); - } - - public void update() - { - // Store the number of players in a team in this map - Map playersOnPoint = new HashMap<>(); - - for (GameTeam team : _host.GetTeamList()) - { - // Populate - playersOnPoint.put(team, 0); - int players = 0; - - for (Player player : team.GetPlayers(true)) - { - // Ignore for spectators - // If they are not in the range - if (UtilPlayer.isSpectator(player) || !isOnPoint(player.getLocation())) - { - continue; - } - - // Increment - players++; - } - - // Put in map - playersOnPoint.put(team, players); - } - - // For each team get the team with the non-zero players - GameTeam highest = null; - int highestPlayers = 0; - for (Entry entry : playersOnPoint.entrySet()) - { - GameTeam team = entry.getKey(); - int players = entry.getValue(); - - // Only care if people are on it - if (players > 0) - { - // If this is the first team on the point - if (highest == null) - { - highest = team; - highestPlayers = players; - } - // This means there are 2 teams on the point - else - { - return; - } - } - } - - // No one at all is on the point - if (highest == null) - { - if (_owner == null) - { - return; - } - - // If the owner isn't null, move the point's progress back - highest = _owner; - highestPlayers = 1; - } - // Players on the point - // Only inform if it has been a while - else if ((_owner == null || !_owner.equals(highest)) && UtilTime.elapsed(_lastInform, MIN_INFORM_TIME)) - { - _lastInform = System.currentTimeMillis(); - - String message = F.main("Game", "Team " + highest.GetFormattedName() + C.mBody + " is capturing the " + _colour + _name + C.mBody + " Beacon!"); - - sendMessage(highest, message); - - if (_owner != null) - { - sendMessage(_owner, message); - } - } - - // If it has just reached the maximum progress, set the owner. - if (_owner != null && _owner.equals(highest) && _progress >= (_owner == null ? MAX_PROGRESS_NEUTRAL : MAX_PROGRESS)) - { - return; - } - - capture(highest, highestPlayers); - } - - private void sendMessage(GameTeam team, String message) - { - team.GetPlayers(true).forEach(player -> - { - player.playSound(player.getLocation(), Sound.GHAST_SCREAM2, 1, 1); - player.sendMessage(message); - }); - } - - private void capture(GameTeam team, int progress) - { - // No player has ever stood on the point - if (_side == null) - { - _side = team; - } - - // If it is the same team - if (_side.equals(team)) - { - // Increase progress - _progress += progress; - display(team, progress, true); - - // Captured - if (_progress >= (_owner == null ? MAX_PROGRESS_NEUTRAL : MAX_PROGRESS)) - { - _progress = MAX_PROGRESS; - setOwner(team); - } - } - // Other team - else - { - // Point back to a neutral state - if (_progress <= 0) - { - setBeaconColour(null); - _side = team; - _progress = 0; - // Recursively call this method now that the first (same team) condition will be true - capture(team, progress); - return; - } - - _progress -= progress; - display(team, progress, false); - } - } - - private void setOwner(GameTeam team) - { - setBeaconColour(team); - - // Same team no need to inform - if (_owner != null && _owner.equals(team)) - { - return; - } - else - { - // As the point is easier to capture after the initial capture - // We need to adjust the current progress, otherwise it has to go - // from 10 to 0 then to 5 which is unintended - _progress = MAX_PROGRESS; - } - - String message = F.main("Game", "Team " + team.GetFormattedName() + C.mBody + " captured the " + _colour + _name + C.mBody + " Beacon!"); - - if (_owner != null) - { - sendMessage(_owner, message); - } - sendMessage(team, message); - - _owner = team; - - UtilFirework.playFirework(_center, Type.BURST, team.GetColorBase(), false, false); - UtilServer.CallEvent(new CapturePointCaptureEvent(this)); - } - - private void display(GameTeam team, int progress, boolean forward) - { - double toChange = Math.ceil(_wool.size() / (_owner == null ? MAX_PROGRESS_NEUTRAL : MAX_PROGRESS)) * progress + 1; - int changed = 0; - for (Block block : _wool) - { - if (changed >= toChange) - { - return; - } - - Block glass = block.getRelative(BlockFace.UP); - - if (forward) - { - if (_changed.contains(block)) - { - continue; - } - - block.setData(team.GetColorData()); - glass.setData(team.GetColorData()); - changed++; - _changed.add(block); - } - else - { - if (!_changed.contains(block)) - { - continue; - } - - block.setData((byte) 0); - glass.setData((byte) 0); - changed++; - _changed.remove(block); - } - - glass.getWorld().playEffect(glass.getLocation().add(0.5, 0.5, 0.5), Effect.STEP_SOUND, block.getType(), team.GetColorData()); - } - } - - private void setBeaconColour(GameTeam team) - { - byte colour = team == null ? 0 : team.GetColorData(); - - _center.getBlock().getRelative(BlockFace.DOWN).setData(colour); - } - - public boolean isOnPoint(Location location) - { - return UtilMath.offsetSquared(_center, location) < _captureDist; - } - - public String getName() - { - return _name; - } - - public ChatColor getColour() - { - return _colour; - } - - public GameTeam getOwner() - { - return _owner; - } - - public Location getCenter() - { - return _center.clone(); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePointCaptureEvent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePointCaptureEvent.java deleted file mode 100644 index 1c2f1d10..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePointCaptureEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -package nautilus.game.arcade.game.modules.capturepoint; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class CapturePointCaptureEvent extends Event -{ - - private static final HandlerList _handlers = new HandlerList(); - - private final CapturePoint _point; - - CapturePointCaptureEvent(CapturePoint point) - { - _point = point; - } - - public CapturePoint getPoint() - { - return _point; - } - - public static HandlerList getHandlerList() - { - return _handlers; - } - - @Override - public HandlerList getHandlers() - { - return getHandlerList(); - } - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePointModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePointModule.java deleted file mode 100644 index e489cbcf..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/capturepoint/CapturePointModule.java +++ /dev/null @@ -1,157 +0,0 @@ -package nautilus.game.arcade.game.modules.capturepoint; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.inventory.BeaconInventory; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.mission.MissionTrackerType; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.missions.GameMissionTracker; - -public class CapturePointModule extends Module -{ - - private final List _capturePoints; - - public CapturePointModule() - { - _capturePoints = new ArrayList<>(3); - } - - @Override - protected void setup() - { - getGame().registerMissions(new GameMissionTracker(MissionTrackerType.GAME_CAPTURE_POINT, getGame()) - { - @EventHandler - public void capturePoint(CapturePointCaptureEvent event) - { - for (Player player : UtilPlayer.getNearby(event.getPoint().getCenter(), CapturePoint.MAX_RADIUS)) - { - if (event.getPoint().getOwner().HasPlayer(player)) - { - _manager.incrementProgress(player, 1, _trackerType, getGameType(), null); - } - } - } - }); - } - - @EventHandler - public void prepare(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Prepare) - { - return; - } - - for (Entry entry : getLocationStartsWith("POINT").entrySet()) - { - String[] split = entry.getKey().split(" "); - - if (split.length < 3) - { - continue; - } - - String name = split[1]; - ChatColor colour; - - try - { - colour = ChatColor.valueOf(split[2]); - } - catch (IllegalArgumentException e) - { - continue; - } - - _capturePoints.add(new CapturePoint(getGame(), name, colour, entry.getValue())); - } - } - - @EventHandler - public void update(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC || !getGame().IsLive()) - { - return; - } - - for (CapturePoint point : _capturePoints) - { - point.update(); - } - } - - @EventHandler - public void beaconInteract(InventoryOpenEvent event) - { - if (getGame().IsLive() && event.getInventory() instanceof BeaconInventory) - { - event.setCancelled(true); - } - } - - public String getDisplayString() - { - StringBuilder out = new StringBuilder(); - - for (CapturePoint point : _capturePoints) - { - out.append(point.getOwner() == null ? C.cWhite : point.getOwner().GetColor()).append(point.getName()).append(" "); - } - - return out.toString().trim(); - } - - public boolean isOnPoint(Location location) - { - for (CapturePoint point : _capturePoints) - { - if (point.isOnPoint(location)) - { - return true; - } - } - - return false; - } - - public List getCapturePoints() - { - return _capturePoints; - } - - private Map getLocationStartsWith(String s) - { - Map map = new HashMap<>(); - - for (String key : getGame().WorldData.GetAllCustomLocs().keySet()) - { - if (key.startsWith(s)) - { - map.put(key, getGame().WorldData.GetCustomLocs(key).get(0)); - } - } - - return map; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootItem.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootItem.java deleted file mode 100644 index 62403cba..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootItem.java +++ /dev/null @@ -1,30 +0,0 @@ -package nautilus.game.arcade.game.modules.chest; - -import mineplex.core.common.util.UtilMath; -import org.bukkit.inventory.ItemStack; - -public class ChestLootItem -{ - - private ItemStack _item; - private int _lowestAmount, _highestAmount; - - ChestLootItem(ItemStack item, int lowestAmount, int highestAmount) - { - _item = item; - _lowestAmount = lowestAmount; - _highestAmount = highestAmount; - } - - public ItemStack getItem() - { - ItemStack itemStack = _item.clone(); - - if (_lowestAmount != _highestAmount) - { - itemStack.setAmount(UtilMath.rRange(_lowestAmount, _highestAmount)); - } - - return itemStack; - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootModule.java deleted file mode 100644 index a673a0b5..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootModule.java +++ /dev/null @@ -1,416 +0,0 @@ -package nautilus.game.arcade.game.modules.chest; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -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.Chest; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.MapUtil; -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.UtilServer; -import mineplex.core.common.util.UtilTime; -import mineplex.core.mission.MissionTrackerType; -import mineplex.core.titles.tracks.standard.LuckyTrack; -import mineplex.core.titles.tracks.standard.UnluckyTrack; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.events.ChestRefillEvent; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.modules.Module; - -public class ChestLootModule extends Module -{ - - private final Map> _chests; - - private long _destroyAfterOpened; - private boolean _autoRotateChests = true, _spawnNearby, _preGenerateLoot; - private int _spawnNearbyRadius = 8; - - public ChestLootModule() - { - _chests = new HashMap<>(); - } - - public ChestLootModule registerChestType(String name, List chestLocations, ChestLootPool... pools) - { - return registerChestType(name, chestLocations, 1, pools); - } - - public ChestLootModule registerChestType(String name, List chestLocations, double spawnChance, ChestLootPool... pools) - { - _chests.put(new ChestType(name, chestLocations, spawnChance, pools), new HashSet<>()); - return this; - } - - public ChestLootModule destroyAfterOpened(int seconds) - { - _destroyAfterOpened = TimeUnit.SECONDS.toMillis(seconds); - return this; - } - - public ChestLootModule autoRotateChests(boolean autoRotate) - { - _autoRotateChests = autoRotate; - return this; - } - - public ChestLootModule spawnNearbyDataPoints() - { - _spawnNearby = true; - return this; - } - - public ChestLootModule spawnNearbyDataPoints(int radius) - { - _spawnNearby = true; - _spawnNearbyRadius = radius; - return this; - } - - public ChestLootModule setPreGenerateLoot(boolean preGenerateLoot) - { - _preGenerateLoot = preGenerateLoot; - return this; - } - - public void addChestLocation(String typeName, Location location) - { - for (Entry> entry : _chests.entrySet()) - { - if (!entry.getKey().Name.equals(typeName)) - { - continue; - } - - entry.getValue().add(new ChestMetadata(location.getBlock(), entry.getKey())); - return; - } - } - - public void refill() - { - _chests.forEach((type, metadataSet) -> metadataSet.forEach(metadata -> metadata.Opened = false)); - - List chests = new ArrayList<>(); - _chests.values().forEach(set -> set.forEach(chestMetadata -> chests.add(chestMetadata.Chest.getLocation()))); - - UtilServer.CallEvent(new ChestRefillEvent(chests)); - } - - public void refill(String typeName) - { - _chests.forEach((type, metadataSet) -> - { - if (!type.Name.equals(typeName)) - { - return; - } - - metadataSet.forEach(metadata -> metadata.Opened = false); - UtilServer.CallEvent(new ChestRefillEvent(metadataSet.stream() - .map(chestMetadata -> chestMetadata.Chest.getLocation()) - .collect(Collectors.toList()))); - }); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void populateChests(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Prepare) - { - return; - } - - for (Entry> entry : _chests.entrySet()) - { - ChestType chestType = entry.getKey(); - - if (chestType.ChestSpawns == null) - { - continue; - } - - Set metadataSet = entry.getValue(); - - for (Location location : chestType.ChestSpawns) - { - if (chestType.SpawnChance == 1 || Math.random() < chestType.SpawnChance) - { - Block block = location.getBlock(); - - if (_spawnNearby) - { - Location nearby = getNearbyLocation(location); - - if (nearby == null) - { - continue; - } - - block = nearby.getBlock(); - } - - block.setType(Material.CHEST); - - if (_autoRotateChests) - { - List faces = new ArrayList<>(UtilBlock.horizontals.size()); - - for (BlockFace face : UtilBlock.horizontals) - { - if (UtilBlock.airFoliage(block.getRelative(face))) - { - faces.add(face); - } - } - - block.setData(getData(UtilAlg.Random(faces))); - } - - ChestMetadata metadata = new ChestMetadata(block, chestType); - metadataSet.add(metadata); - - if (_preGenerateLoot) - { - metadata.populateChest((Chest) block.getState()); - } - } - else - { - MapUtil.QuickChangeBlockAt(location, Material.AIR); - } - } - - _chests.put(chestType, metadataSet); - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void openChest(PlayerInteractEvent event) - { - Block block = event.getClickedBlock(); - - if (event.isCancelled() || !UtilEvent.isAction(event, ActionType.R_BLOCK) || block == null || !(block.getState() instanceof Chest)) - { - return; - } - - ChestMetadata metadata = getFromBlock(block); - - if (metadata == null || metadata.Opened) - { - return; - } - - Chest chest = (Chest) block.getState(); - Player player = event.getPlayer(); - ArcadeManager manager = getGame().getArcadeManager(); - getGame().AddStat(player, "ChestsOpened", 1, false, false); - getGame().getArcadeManager().getMissionsManager().incrementProgress(player, 1, MissionTrackerType.GAME_CHEST_OPEN, getGame().GetType().getDisplay(), metadata.Type.Name); - - if (manager.IsRewardStats()) - { - manager.getTrackManager().getTrack(LuckyTrack.class).handleLoot(player, chest.getBlockInventory()); - manager.getTrackManager().getTrack(UnluckyTrack.class).handleLoot(player, chest.getBlockInventory()); - } - - metadata.Opened = true; - metadata.OpenedAt = System.currentTimeMillis(); - - if (!_preGenerateLoot) - { - metadata.populateChest(chest); - } - } - - @EventHandler - public void destroyOpenedChests(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC || _destroyAfterOpened == 0) - { - return; - } - - for (Set metadataSet : _chests.values()) - { - metadataSet.removeIf(metadata -> - { - if (metadata.Opened && UtilTime.elapsed(metadata.OpenedAt, _destroyAfterOpened)) - { - Block block = metadata.Chest; - Location location = block.getLocation(); - location.getWorld().playEffect(location.add(0.5, 0.5, 0.5), Effect.STEP_SOUND, block.getType()); - if (block.getType() == Material.CHEST) - { - ((Chest) block.getState()).getBlockInventory().clear(); - } - MapUtil.QuickChangeBlockAt(location, Material.AIR); - return true; - } - - return false; - }); - } - } - - public ItemStack getRandomItem(String chestTypeName) - { - for (ChestType chestType1 : _chests.keySet()) - { - if (!chestType1.Name.equals(chestTypeName)) - { - continue; - } - - ChestLootPool pool = UtilAlg.Random(chestType1.Pools); - - if (pool == null) - { - return null; - } - - return pool.getRandomItem(); - } - - return null; - } - - private ChestMetadata getFromBlock(Block block) - { - for (Set metadataSet : _chests.values()) - { - for (ChestMetadata metadata : metadataSet) - { - if (metadata.Chest.getLocation().getBlock().equals(block)) - { - return metadata; - } - } - } - - return null; - } - - private byte getData(BlockFace face) - { - if (face == null) - { - return 0; - } - - switch (face) - { - case NORTH: - return 0; - case SOUTH: - return 3; - case WEST: - return 4; - case EAST: - return 5; - } - - return 0; - } - - private Location getNearbyLocation(Location center) - { - int attempts = 0; - while (attempts++ < 20) - { - Location newLocation = UtilAlg.getRandomLocation(center, _spawnNearbyRadius, 1, _spawnNearbyRadius); - - if (isSuitable(newLocation.getBlock())) - { - return newLocation; - } - } - - return null; - } - - private boolean isSuitable(Block block) - { - Block up = block.getRelative(BlockFace.UP); - Block down = block.getRelative(BlockFace.DOWN); - - return block.getType() == Material.AIR && up.getType() == Material.AIR && down.getType() != Material.AIR && !UtilBlock.liquid(down) && !UtilBlock.liquid(up) && !UtilBlock.liquid(block); - } - - private class ChestMetadata - { - - Block Chest; - ChestType Type; - long OpenedAt; - boolean Opened; - - ChestMetadata(Block chest, ChestType type) - { - Chest = chest; - Type = type; - } - - void populateChest(Chest chest) - { - Inventory inventory = chest.getBlockInventory(); - inventory.clear(); - List slots = new ArrayList<>(chest.getBlockInventory().getSize()); - - for (int i = 0; i < inventory.getSize(); i++) - { - slots.add(i); - } - - for (ChestLootPool pool : Type.Pools) - { - if (pool.getProbability() == 1 || Math.random() < pool.getProbability()) - { - pool.populateChest(chest, slots); - } - } - } - } - - private class ChestType - { - String Name; - double SpawnChance; - List Pools; - List ChestSpawns; - - ChestType(String name, List chestLocations, double spawnChance, ChestLootPool... pools) - { - Name = name; - SpawnChance = spawnChance; - Pools = Arrays.asList(pools); - ChestSpawns = chestLocations; - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootPool.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootPool.java deleted file mode 100644 index ecb5ce4b..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/chest/ChestLootPool.java +++ /dev/null @@ -1,137 +0,0 @@ -package nautilus.game.arcade.game.modules.chest; - -import java.util.AbstractMap.SimpleEntry; -import java.util.List; -import java.util.Map.Entry; - -import org.bukkit.block.Chest; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.UtilItem; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.weight.WeightSet; - -public class ChestLootPool -{ - - private static final int DEFAULT_RARITY = 100; - - private final WeightSet _items; - private final WeightSet> _enchantments; - private int _minimumPerChest, _maximumPerChest; - private double _rarity, _enchantmentRarity; - private boolean _unbreakable; - - public ChestLootPool() - { - _items = new WeightSet<>(); - _enchantments = new WeightSet<>(); - _minimumPerChest = 1; - _maximumPerChest = 1; - _rarity = 1; - } - - public ChestLootPool addItem(ItemStack itemStack) - { - return addItem(itemStack, itemStack.getAmount(), itemStack.getAmount(), DEFAULT_RARITY); - } - - public ChestLootPool addItem(ItemStack itemStack, int rarity) - { - return addItem(itemStack, itemStack.getAmount(), itemStack.getAmount(), rarity); - } - - public ChestLootPool addItem(ItemStack itemStack, int lowestAmount, int highestAmount) - { - return addItem(itemStack, lowestAmount, highestAmount, DEFAULT_RARITY); - } - - public ChestLootPool addItem(ItemStack itemStack, int lowestAmount, int highestAmount, int rarity) - { - _items.add(rarity, new ChestLootItem(itemStack, lowestAmount, highestAmount)); - return this; - } - - public ChestLootPool addEnchantment(Enchantment enchantment, int maxLevel) - { - return addEnchantment(enchantment, maxLevel, DEFAULT_RARITY); - } - - public ChestLootPool addEnchantment(Enchantment enchantment, int maxLevel, int rarity) - { - _enchantments.add(rarity, new SimpleEntry<>(enchantment, maxLevel)); - return this; - } - - public ChestLootPool setEnchantmentRarity(double probability) - { - _enchantmentRarity = probability; - return this; - } - - public ChestLootPool setAmountsPerChest(int minimumPerChest, int maximumPerChest) - { - _minimumPerChest = minimumPerChest; - _maximumPerChest = maximumPerChest; - return this; - } - - public ChestLootPool setProbability(double probability) - { - _rarity = probability; - return this; - } - - public ChestLootPool setUnbreakable(boolean unbreakable) - { - _unbreakable = unbreakable; - return this; - } - - public void populateChest(Chest chest, List slots) - { - Inventory inventory = chest.getBlockInventory(); - - for (int i = 0; i < UtilMath.rRange(_minimumPerChest, _maximumPerChest); i++) - { - int slot = UtilMath.r(slots.size()); - slots.remove(slot); - inventory.setItem(slot, getRandomItem()); - } - - chest.update(); - } - - public ItemStack getRandomItem() - { - ChestLootItem item = _items.generateRandom(); - - if (item == null) - { - return null; - } - - ItemStack itemStack = item.getItem(); - - if (_enchantments.elements() != null && Math.random() < _enchantmentRarity) - { - Entry enchantment = _enchantments.generateRandom(); - - itemStack.addUnsafeEnchantment(enchantment.getKey(), UtilMath.r(enchantment.getValue()) + 1); - } - - if (_unbreakable && itemStack.getType().getMaxDurability() > 0) - { - UtilItem.makeUnbreakable(itemStack); - } - - return itemStack; - } - - public double getProbability() - { - return _rarity; - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/combattracker/CombatData.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/combattracker/CombatData.java deleted file mode 100644 index c2fc669b..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/combattracker/CombatData.java +++ /dev/null @@ -1,28 +0,0 @@ -package nautilus.game.arcade.game.modules.combattracker; - -public class CombatData -{ - - private int _kills, _assits; - - public void incrementKills() - { - _kills++; - } - - public int getKills() - { - return _kills; - } - - public void incrementAssists() - { - _assits++; - } - - - public int getAssits() - { - return _assits; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/combattracker/CombatTrackerModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/combattracker/CombatTrackerModule.java deleted file mode 100644 index 510a0ff0..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/combattracker/CombatTrackerModule.java +++ /dev/null @@ -1,72 +0,0 @@ -package nautilus.game.arcade.game.modules.combattracker; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; - -import mineplex.core.common.util.UtilPlayer; -import mineplex.minecraft.game.core.combat.CombatComponent; -import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; - -import nautilus.game.arcade.game.modules.Module; - -public class CombatTrackerModule extends Module -{ - - private final Map _combatData; - - public CombatTrackerModule() - { - _combatData = new HashMap<>(); - } - - public CombatData getCombatData(Player player) - { - return _combatData.computeIfAbsent(player.getUniqueId(), k -> new CombatData()); - } - - @Override - public void cleanup() - { - _combatData.clear(); - } - - @EventHandler - public void combatDeath(CombatDeathEvent event) - { - if (!(event.GetEvent().getEntity() instanceof Player)) - { - return; - } - - Player killed = (Player) event.GetEvent().getEntity(); - - if (event.GetLog().GetKiller() != null) - { - Player killer = UtilPlayer.searchExact(event.GetLog().GetKiller().GetName()); - - if (killer != null && !killer.equals(killed)) - { - getCombatData(killer).incrementKills(); - } - } - - for (CombatComponent log : event.GetLog().GetAttackers()) - { - if (event.GetLog().GetKiller() != null && log.equals(event.GetLog().GetKiller())) - { - continue; - } - - Player assist = UtilPlayer.searchExact(log.GetName()); - - if (assist != null) - { - getCombatData(assist).incrementAssists(); - } - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassAttemptTargetEvent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassAttemptTargetEvent.java deleted file mode 100644 index 7ecb57e1..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassAttemptTargetEvent.java +++ /dev/null @@ -1,50 +0,0 @@ -package nautilus.game.arcade.game.modules.compass; - -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; - -public class CompassAttemptTargetEvent extends PlayerEvent implements Cancellable -{ - private static HandlerList _handlers = new HandlerList(); - private boolean _cancelled = false; - - private Entity _target; - - CompassAttemptTargetEvent(Player player, Entity target) - { - super(player); - - _target = target; - } - - public Entity getTarget() - { - return _target; - } - - public static HandlerList getHandlerList() - { - return _handlers; - } - - @Override - public HandlerList getHandlers() - { - return getHandlerList(); - } - - @Override - public boolean isCancelled() - { - return _cancelled; - } - - @Override - public void setCancelled(boolean cancelled) - { - _cancelled = cancelled; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassEntry.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassEntry.java deleted file mode 100644 index 7f22908c..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassEntry.java +++ /dev/null @@ -1,49 +0,0 @@ -package nautilus.game.arcade.game.modules.compass; - -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.kit.Kit; - -import org.bukkit.entity.Entity; - -public class CompassEntry -{ - private Entity _entity; - private String _name; - private String _displayName; - private GameTeam _team; - private Kit _kit; - - public CompassEntry(Entity entity, String name, String displayName, GameTeam team, Kit kit) - { - _entity = entity; - _name = name; - _displayName = displayName; - _team = team; - _kit = kit; - } - - public Entity getEntity() - { - return _entity; - } - - public GameTeam getTeam() - { - return _team; - } - - public String getDisplayName() - { - return _displayName; - } - - public String getName() - { - return _name; - } - - public Kit getKit() - { - return _kit; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassModule.java deleted file mode 100644 index fa5846ba..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/CompassModule.java +++ /dev/null @@ -1,253 +0,0 @@ -package nautilus.game.arcade.game.modules.compass; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilInv; -import mineplex.core.common.util.UtilItem; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilTextBottom; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.game.modules.compass.menu.CompassMenu; - -public class CompassModule extends Module -{ - - private static final ItemStack COMPASS_ITEM = - new ItemBuilder(Material.COMPASS) - .setAmount(1) - .setTitle(C.cGreenB + "Tracking Compass") - .build(); - - public static ItemStack getCompassItem() - { - return COMPASS_ITEM; - } - - private List>> _suppliers = new ArrayList<>(); - - private CompassMenu _compassMenu; - private boolean _giveCompassToAlive = false; - private boolean _giveCompassItem = true; - private boolean _giveCompassItemToSpectators = true; - - public CompassModule addSupplier(Supplier> supplier) - { - _suppliers.add(supplier); - return this; - } - - public CompassModule setGiveCompassToAlive(boolean b) - { - _giveCompassToAlive = b; - return this; - } - - public CompassModule setGiveCompass(boolean b) - { - _giveCompassItem = b; - return this; - } - - public CompassModule setGiveCompassToSpecs(boolean b) - { - _giveCompassItemToSpectators = b; - return this; - } - - @Override - public void cleanup() - { - HandlerList.unregisterAll(_compassMenu); - _compassMenu = null; - _suppliers = null; - UtilServer.getPlayersCollection().forEach(player -> ((CraftPlayer) player).getHandle().compassTarget = null); - } - - @Override - protected void setup() - { - _compassMenu = new CompassMenu(this); - _suppliers.add(() -> - getGame() - .GetPlayers(true) - .stream() - .map(player -> new CompassEntry(player, player.getName(), player.getName(), getGame().GetTeam(player), getGame().GetKit(player))) - .collect(Collectors.toList())); - } - - @EventHandler - public void update(UpdateEvent event) - { - if (event.getType() != UpdateType.FASTER) - return; - - if (!getGame().IsLive()) - return; - - for (Player player : UtilServer.getPlayers()) - { - if (!_giveCompassToAlive && getGame().IsAlive(player)) - continue; - - GameTeam team = getGame().GetTeam(player); - - stream() - .filter(entry -> entry.getEntity() != player) - .filter(entry -> getGame().GetTeamList().size() <= 1 || team == null || !team.equals(entry.getTeam())) - .filter(entry -> !UtilServer.CallEvent(new CompassAttemptTargetEvent(player, entry.getEntity())).isCancelled()) - .min(Comparator.comparingDouble(a -> UtilMath.offset(player, a.getEntity()))) - .ifPresent(target -> - { - Entity targetEntity = target.getEntity(); - GameTeam targetTeam = target.getTeam(); - - if (_giveCompassItem || (_giveCompassItemToSpectators && getGame().getArcadeManager().isSpectator(player))) - { - long count = UtilInv.getItems(player, true, true, true) - .stream() - .filter(this::isCompassItem) - .count(); - - if (count == 0) - { - player.getInventory().addItem(COMPASS_ITEM); - } - } - - - player.setCompassTarget(targetEntity.getLocation()); - - double heightDiff = targetEntity.getLocation().getY() - player.getLocation().getY(); - - //Action Bar - if (isCompassItem(player.getItemInHand())) - { - UtilTextBottom.display( - " " + C.cWhite + C.Bold + "Nearest Target: " + targetTeam.GetColor() + target.getDisplayName() + - " " + C.cWhite + C.Bold + "Distance: " + targetTeam.GetColor() + UtilMath.trim(1, UtilMath.offset(player, targetEntity)) + - " " + C.cWhite + C.Bold + "Height: " + targetTeam.GetColor() + UtilMath.trim(1, heightDiff), player - ); - } - }); - } - } - - @EventHandler - public void onDrop(PlayerDropItemEvent event) - { - if (!isCompassItem(event.getItemDrop().getItemStack())) - return; - - event.setCancelled(true); - - UtilPlayer.message(event.getPlayer(), F.main("Game", "You cannot drop " + F.item("Target Compass") + ".")); - } - - @EventHandler - public void DeathRemove(PlayerDeathEvent event) - { - event.getDrops().removeIf(this::isCompassItem); - } - - @EventHandler - public void SpectatorTeleport(PlayerInteractEvent event) - { - if (event.getAction() == Action.PHYSICAL) - return; - - Player player = event.getPlayer(); - - if (getGame().IsAlive(player)) - return; - - if (!isCompassItem(player.getItemInHand())) - return; - - if (player.getGameMode() == GameMode.SPECTATOR) - return; - - event.setCancelled(true); - - if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) - { - if (!Recharge.Instance.use(player, "Spectate", 3000, true, false)) - { - return; - } - - spectateNearestPlayer(player); - } - else - { - _compassMenu.attemptShopOpen(player); - } - } - - private void spectateNearestPlayer(Player spectator) - { - stream() - .min((a, b) -> Double.compare(UtilMath.offset(spectator, a.getEntity()), UtilMath.offset(spectator, b.getEntity()))) - .map(CompassEntry::getEntity) - .ifPresent(target -> spectator.teleport(target.getLocation().add(0, 1, 0))); - } - - @EventHandler - public void closeShop(GameStateChangeEvent event) - { - if (event.GetState().equals(Game.GameState.End)) - { - UtilServer.getPlayersCollection().stream().filter(_compassMenu::isPlayerInShop).forEach(Player::closeInventory); - } - } - - @EventHandler - public void updateShop(UpdateEvent event) - { - if (event.getType() != UpdateType.SEC) - return; - - _compassMenu.update(); - } - - public Stream stream() - { - return _suppliers.stream().map(Supplier::get).flatMap(Collection::stream); - } - - // Defined here to make modifying definitions easier - public boolean isCompassItem(ItemStack item) - { - return UtilItem.isSimilar(COMPASS_ITEM, item, UtilItem.ItemAttribute.NAME, UtilItem.ItemAttribute.MATERIAL); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/CompassMenu.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/CompassMenu.java deleted file mode 100644 index 2c11196c..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/CompassMenu.java +++ /dev/null @@ -1,37 +0,0 @@ -package nautilus.game.arcade.game.modules.compass.menu; - -import org.bukkit.entity.Player; - -import mineplex.core.shop.ShopBase; -import mineplex.core.shop.page.ShopPageBase; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.modules.compass.CompassModule; -import nautilus.game.arcade.game.modules.compass.menu.page.CompassPage; - -public class CompassMenu extends ShopBase -{ - private CompassModule _compassModule; - - public CompassMenu(CompassModule module) - { - super(module.getGame(), module.getGame().getArcadeManager().GetClients(), module.getGame().getArcadeManager().GetDonation(), "Spectate Menu"); - this._compassModule = module; - } - - @Override - protected ShopPageBase> buildPagesFor(Player player) - { - return new CompassPage(this, _compassModule, player); - } - - public void update() - { - for (ShopPageBase> shopPage : getPlayerPageMap().values()) - { - shopPage.refresh(); - } - } - -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/button/CompassButton.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/button/CompassButton.java deleted file mode 100644 index ae6c23b6..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/button/CompassButton.java +++ /dev/null @@ -1,78 +0,0 @@ -package nautilus.game.arcade.game.modules.compass.menu.button; - -import java.lang.ref.WeakReference; - -import mineplex.core.common.util.F; -import mineplex.core.shop.item.IButton; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.modules.compass.CompassEntry; - -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; - -/** - * Created by shaun on 14-09-26. - */ -public class CompassButton implements IButton -{ - private ArcadeManager _arcadeManager; - private Player _player; - private WeakReference _target; - - public CompassButton(ArcadeManager arcadeManager, Player player, CompassEntry target) - { - _arcadeManager = arcadeManager; - _player = player; - _target = new WeakReference<>(target.getEntity()); - } - - @Override - public void onClick(Player player, ClickType clickType) - { - // Make sure this player is still a spectator - if (!((CraftPlayer) player).getHandle().spectating) - return; - - if (_target.get() == null) - { - _player.sendMessage(F.main("Spectate", "That target does not exist anymore")); - return; - } - - Entity entity = _target.get(); - if (entity instanceof Player) - { - if (_arcadeManager.IsAlive((Player) entity)) - { - if (clickType == ClickType.RIGHT) - { - _player.closeInventory(); - _arcadeManager.getGameSpectatorManager().setSpectating(_player, entity); - } - else - { - _player.teleport(entity.getLocation().add(0, 1, 0)); - } - } - else - { - _player.sendMessage(F.main("Spectate", F.name(entity.getName()) + " is no longer alive.")); - } - } - else - { - if (clickType == ClickType.RIGHT) - { - _player.closeInventory(); - _arcadeManager.getGameSpectatorManager().setSpectating(_player, entity); - } - else - { - _player.teleport(entity.getLocation().add(0, 1, 0)); - } - } - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/page/CompassPage.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/page/CompassPage.java deleted file mode 100644 index a4f88d31..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/compass/menu/page/CompassPage.java +++ /dev/null @@ -1,227 +0,0 @@ -package nautilus.game.arcade.game.modules.compass.menu.page; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilColor; -import mineplex.core.common.util.UtilMath; -import mineplex.core.shop.item.IButton; -import mineplex.core.shop.item.ShopItem; -import mineplex.core.shop.page.ShopPageInventory; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.modules.compass.CompassEntry; -import nautilus.game.arcade.game.modules.compass.CompassModule; -import nautilus.game.arcade.game.modules.compass.menu.CompassMenu; -import nautilus.game.arcade.game.modules.compass.menu.button.CompassButton; - -public class CompassPage extends - ShopPageInventory -{ - private CompassModule _compassModule; - private IButton[] _buttons; - private ItemStack[] _items; - - public CompassPage(CompassMenu menu, CompassModule compassModule, Player player) - { - super(compassModule.getGame(), - menu, - compassModule.getGame().getArcadeManager().GetClients(), - compassModule.getGame().getArcadeManager().GetDonation(), - "Spectator Menu", - player); - _compassModule = compassModule; - buildPage(); - } - - @Override - protected void buildItems() - { - _buttons = new IButton[54]; - _items = new ItemStack[54]; - - List teamList = new ArrayList<>(_compassModule.getGame().GetTeamList()); - List entries = _compassModule.stream().collect(Collectors.toList()); - - if (teamList.size() == 1 && entries.size() < 28) - { - buildSingleTeam(teamList.get(0), entries); - } - else - { - buildMultipleTeams(teamList, entries); - } - } - - private void buildSingleTeam(GameTeam team, List entries) - { - Collections.sort(entries, (o1, o2) -> o1.getDisplayName().compareToIgnoreCase(o2.getDisplayName())); - - _buttons = new IButton[19 + entries.size()]; - _items = new ItemStack[_buttons.length]; - - _items[13] = getTeamItem(team, entries.size()); - - int slot = 19; - - for (CompassEntry other : entries) - { - addPlayerItem(slot, team, other); - - if ((slot + 2) % 9 == 0) - { - _buttons = Arrays.copyOf(_buttons, _buttons.length + 3); - _items = Arrays.copyOf(_items, _items.length + 3); - - slot += 3; - } - else - { - slot++; - } - } - } - - private void buildMultipleTeams(List teamList, List entries) - { - Collections.sort(teamList, (o1, o2) -> - { - int returns = o1.getDisplayName().compareToIgnoreCase( - o2.getDisplayName()); - - if (returns == 0) - { - return Long.compare(o1.getCreatedTime(), - o2.getCreatedTime()); - } - - return returns; - }); - - _buttons = new IButton[0]; - _items = new ItemStack[0]; - - int currentRow = 0; - - for (GameTeam team : teamList) - { - List teamPlayers = entries.stream().filter(ent -> ent.getTeam() == team).collect(Collectors.toList()); - - Collections.sort(teamPlayers, (o1, o2) -> o1.getDisplayName().compareToIgnoreCase(o2.getDisplayName())); - - int rowsNeeded = (int) Math.ceil(teamPlayers.size() / 8.0); - - _buttons = Arrays.copyOf(_buttons, _buttons.length + (rowsNeeded * 9)); - _items = Arrays.copyOf(_items, _items.length + (rowsNeeded * 9)); - - for (int row = 0; row < rowsNeeded; row++) - { - int woolSlot = (row * 9) + (currentRow * 9); - - _items[woolSlot] = getTeamItem(team, teamPlayers.size()); - - int playerIndex = row * 8; - for (int i = 0; i < 8 && playerIndex < teamPlayers.size(); i++, playerIndex++) - { - CompassEntry other = teamPlayers.get(playerIndex); - int slot = woolSlot + 1 + i; - - addPlayerItem(slot, team, other); - } - } - - // Add a line in between teams if the player count is low enough and - // there are less than 4 teams - if (rowsNeeded == 1 && teamList.size() < 4 && entries.size() <= 26) - { - currentRow += 2; - - _buttons = Arrays.copyOf(_buttons, _buttons.length + 9); - _items = Arrays.copyOf(_items, _items.length + 9); - } - else - { - currentRow += rowsNeeded; - } - } - } - - private void addPlayerItem(int slot, GameTeam team, CompassEntry other) - { - ItemStack playerItem = getPlayerItem(team, other); - - ShopItem shopItem = new ShopItem(playerItem, other.getDisplayName(), - other.getDisplayName(), 1, false, false); - - _items[slot] = shopItem; - _buttons[slot] = new CompassButton(_compassModule.getGame().getArcadeManager(), getPlayer(), other); - } - - private ItemStack getTeamItem(GameTeam team, int playerCount) - { - ItemStack item = new ItemStack(Material.WOOL, 1, (short) 0, - UtilColor.chatColorToWoolData(team.GetColor())); - - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(team.GetFormattedName()); - meta.setLore(Arrays.asList(" ", ChatColor.RESET + C.cYellow - + "Players Alive: " + C.cWhite + playerCount)); - item.setItemMeta(meta); - - return item; - } - - private ItemStack getPlayerItem(GameTeam team, CompassEntry other) - { - ItemStack item = new ItemStack(Material.SKULL_ITEM, 1, (byte) 3); - - double distance = UtilMath.offset(getPlayer(), other.getEntity()); - double heightDifference = other.getEntity().getLocation().getY() - - getPlayer().getLocation().getY(); - - ArrayList lore = new ArrayList(); - lore.add(" "); - lore.add(ChatColor.RESET + C.cYellow + "Kit: " + C.cWhite - + other.getKit().GetName()); - lore.add(ChatColor.RESET + C.cYellow + "Distance: " + C.cWhite - + UtilMath.trim(1, distance)); - lore.add(ChatColor.RESET + C.cYellow + "Height Difference: " + C.cWhite - + UtilMath.trim(1, heightDifference)); - lore.add(" "); - lore.add(ChatColor.YELLOW + "Left Click" + ChatColor.RESET + " Teleport"); - lore.add(ChatColor.YELLOW + "Right Click" + ChatColor.RESET + " Spectate"); - SkullMeta skullMeta = ((SkullMeta) item.getItemMeta()); - skullMeta.setOwner(other.getName()); - skullMeta.setDisplayName(team.GetColor() + other.getDisplayName()); - skullMeta.setLore(lore); - item.setItemMeta(skullMeta); - - return item; - } - - @Override - protected IButton[] getButtons() - { - return _buttons; - } - - @Override - protected ItemStack[] getItems() - { - return _items; - } - -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryComponent.java deleted file mode 100644 index b986e0b9..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryComponent.java +++ /dev/null @@ -1,73 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary; - -import java.util.List; -import java.util.function.Function; - -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.HoverEvent.Action; -import net.md_5.bungee.api.chat.TextComponent; - -import org.bukkit.entity.Player; - -public abstract class GameSummaryComponent -{ - - protected static final String DOUBLE_ARROW = "»"; - - private final GameSummaryComponentType _type; - private final Function _getFunction; - - public GameSummaryComponent(GameSummaryComponentType type, Function getFunction) - { - _type = type; - _getFunction = getFunction; - } - - public abstract String getMainText(T data); - - public abstract List getHoverText(T data); - - public boolean sendMessage(Player player) - { - T result = _getFunction.apply(player); - if (result == null) - { - return false; - } - - String mainText = getMainText(result); - List hoverText = getHoverText(result); - - if (mainText == null || hoverText == null) - { - return false; - } - - BaseComponent[] message = TextComponent.fromLegacyText(mainText); - String hoverTextString = String.join("\n", hoverText); - - if (!hoverTextString.isEmpty()) - { - HoverEvent hoverEvent = new HoverEvent(Action.SHOW_TEXT, TextComponent.fromLegacyText(hoverTextString)); - - for (BaseComponent component : message) - { - component.setHoverEvent(hoverEvent); - } - } - - player.spigot().sendMessage(message); - return true; - } - - protected void sendBlank(Player player) - { - player.sendMessage(""); - } - - public GameSummaryComponentType getType() - { - return _type; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryComponentType.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryComponentType.java deleted file mode 100644 index 7e732890..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryComponentType.java +++ /dev/null @@ -1,18 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary; - -public enum GameSummaryComponentType -{ - - // Standard - GEMS, - SHARDS, - EXPERIENCE, - LEVEL_UP, - KIT, - ACHIEVEMENT, - - // Custom - WIN_STREAK, - EV_KIT, - CUSTOM_REWARD -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryModule.java deleted file mode 100644 index 4e69309e..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/GameSummaryModule.java +++ /dev/null @@ -1,146 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; - -import mineplex.core.achievement.Achievement; -import mineplex.core.achievement.AchievementData; -import mineplex.core.achievement.AchievementLog; -import mineplex.core.achievement.AchievementManager; -import mineplex.core.common.Pair; -import mineplex.core.common.currency.GlobalCurrency; -import mineplex.core.common.jsonchat.HoverEvent; -import mineplex.core.common.jsonchat.JsonMessage; -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilServer; - -import nautilus.game.arcade.ArcadeFormat; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.game.modules.gamesummary.components.AchievementSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.components.ExperienceSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.components.GemSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.components.KitSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.components.LevelUpSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.components.ShardSummaryComponent; - -public class GameSummaryModule extends Module -{ - - private final List> _components; - - public GameSummaryModule() - { - _components = new ArrayList<>(8); - } - - @Override - protected void setup() - { - setupDefaultComponents(); - } - - @Override - public void cleanup() - { - _components.clear(); - } - - public GameSummaryModule addComponent(GameSummaryComponent component) - { - _components.add(component); - return this; - } - - public GameSummaryModule replaceComponent(GameSummaryComponentType type, GameSummaryComponent newComponent) - { - for (int i = 0; i < _components.size(); i++) - { - if (_components.get(i).getType().equals(type)) - { - _components.set(i, newComponent); - break; - } - } - - return this; - } - - private void setupDefaultComponents() - { - Function> experienceFunction = player -> - { - AchievementManager manager = getGame().getArcadeManager().GetAchievement(); - AchievementLog log = manager.getLog(player).get(Achievement.GLOBAL_MINEPLEX_LEVEL); - AchievementData data = manager.get(player, Achievement.GLOBAL_MINEPLEX_LEVEL); - - return Pair.create(log, data); - }; - - addComponent(new GemSummaryComponent(player -> getGame().GetGems(player), GlobalCurrency.GEM.getColor(), GlobalCurrency.GEM.getPrefix())); - addComponent(new ShardSummaryComponent(getGame().getArcadeManager(), player -> Pair.create(player, getGame().getArcadeManager().getGameRewardManager().getBaseShardsEarned(player)))); - addComponent(new ExperienceSummaryComponent(experienceFunction)); - addComponent(new LevelUpSummaryComponent(experienceFunction)); - addComponent(new AchievementSummaryComponent(getGame().getArcadeManager())); - addComponent(new KitSummaryComponent(getGame().getArcadeManager())); - } - - @EventHandler - public void gameDisable(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Dead) - { - return; - } - - ArcadeManager manager = getGame().getArcadeManager(); - - if (!manager.IsRewardGems() || !manager.IsRewardStats() || !manager.IsRewardAchievements() || manager.GetGame().getGameLiveTime() == 0) - { - return; - } - - UtilServer.getPlayersCollection().forEach(this::informRewards); - } - - private void informRewards(Player player) - { - if (!getGame().getArcadeManager().hasBeenPlaying(player)) - { - return; - } - - player.sendMessage(ArcadeFormat.Line); - - player.sendMessage(C.Bold + "Game Rewards"); - player.sendMessage(""); - - _components.forEach(component -> - { - try - { - component.sendMessage(player); - } - catch (Exception e) - { - e.printStackTrace(); - } - }); - - new JsonMessage(C.cGray + "Hover over for details.") - .hover(HoverEvent.SHOW_TEXT, C.cGray + "Don't hover over me, silly!") - .sendToPlayer(player); - player.sendMessage(ArcadeFormat.Line); - - player.playSound(player.getLocation(), Sound.LEVEL_UP, 2, 1); - - getGame().getArcadeManager().GetAchievement().clearLog(player); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/AchievementSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/AchievementSummaryComponent.java deleted file mode 100644 index 9b662933..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/AchievementSummaryComponent.java +++ /dev/null @@ -1,212 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.bukkit.entity.Player; - -import mineplex.core.achievement.Achievement; -import mineplex.core.achievement.AchievementData; -import mineplex.core.achievement.AchievementManager; -import mineplex.core.common.currency.GlobalCurrency; -import mineplex.core.common.jsonchat.HoverEvent; -import mineplex.core.common.jsonchat.JsonMessage; -import mineplex.core.common.util.C; -import mineplex.core.donation.DonationManager; -import mineplex.core.stats.StatsManager; -import mineplex.core.task.TaskManager; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; - -public class AchievementSummaryComponent extends ComplexSummaryComponent -{ - - private final AchievementManager _achievementManager; - private final DonationManager _donationManager; - private final StatsManager _statsManager; - private final TaskManager _taskManager; - - public AchievementSummaryComponent(ArcadeManager manager) - { - super(GameSummaryComponentType.ACHIEVEMENT); - - _achievementManager = manager.GetAchievement(); - _donationManager = manager.GetDonation(); - _statsManager = manager.GetStatsManager(); - _taskManager = manager.GetTaskManager(); - } - - @Override - public boolean sendMessage(Player player) - { - AtomicInteger progressFor = new AtomicInteger(); - StringBuilder hoverTextBuilder = new StringBuilder(100); - - _achievementManager.getLog(player).forEach((achievement, log) -> - { - AchievementData data = _achievementManager.get(player, achievement); - - if (log.LevelUp) - { - String nameLevel = getAchievementName(achievement, data); - - StringBuilder description = new StringBuilder(); - - for (String line : achievement.getDesc()) - { - description.append("\n").append(C.cDAqua).append(line); - } - - int[] rewards = getRewards(achievement, data.getLevel()); - String title; - String reward = getRewardsString(player, rewards); - - if (data.getLevel() >= achievement.getMaxLevel()) - { - title = C.cPurpleB + "Achievement Get! "; - - _taskManager.completedTask(success -> - { - if (success) - { - _donationManager.rewardCurrencyUntilSuccess(GlobalCurrency.GEM, player, achievement.getName(), achievement.getGemReward()); - rewardPlayer(player, achievement, rewards); - } - }, player, achievement.getName()); - } - else - { - title = C.cPurpleB + "Achievement Level Up! "; - - rewardPlayer(player, achievement, rewards); - } - - if (!reward.isEmpty()) - { - reward = "\n\n" + reward; - } - - new JsonMessage(title + C.cGray + nameLevel) - .hover(HoverEvent.SHOW_TEXT, - C.cAquaB + nameLevel + "\n" + - C.cDAqua + description.toString().substring(1) + - reward - ) - .sendToPlayer(player); - } - else if (!_taskManager.hasCompletedTask(player, achievement.getName()) && data.getExpNextLevel() != -1) - { - String nameLevel = getAchievementName(achievement, data); - - StringBuilder description = new StringBuilder(); - - for (String line : achievement.getDesc()) - { - description.append("\n").append(C.cDAqua).append(line); - } - - hoverTextBuilder - .append("\n\n") - .append(C.cAquaB).append(nameLevel) - .append("\n") - .append(description.toString().substring(1)) - .append("\n") - .append(C.cPurple).append(data.getExpRemainder()).append("/").append(data.getExpNextLevel()).append(C.cGray).append(" (+").append(log.Amount).append(")"); - - progressFor.getAndIncrement(); - } - }); - - if (progressFor.get() == 0) - { - return false; - } - - new JsonMessage(C.cGray + "Progress for " + C.cYellow + progressFor.get() + " Achievement" + (progressFor.get() == 1 ? "" : "s")) - .hover(HoverEvent.SHOW_TEXT, hoverTextBuilder.toString().substring(2)) - .sendToPlayer(player); - - sendBlank(player); - return true; - } - - private String getAchievementName(Achievement achievement, AchievementData data) - { - String nameLevel = achievement.getName(); - - if (achievement.getMaxLevel() > 1) - { - if (achievement.hasLevelNames()) - { - String tier = data.getLevel() == 0 ? achievement.getDefaultLevelName() : achievement.getLevelNames()[Math.min(data.getLevel(), achievement.getLevelNames().length) - 1]; - nameLevel += " " + tier; - } - else - { - nameLevel += " " + (data.getLevel() + (achievement == Achievement.GLOBAL_GEM_HUNTER ? 1 : 0)); - } - } - - return nameLevel; - } - - private int[] getRewards(Achievement achievement, int level) - { - int gems = 0; - int crowns = 0; - int xp = 0; - - if (achievement.getLevelUpRewards().length > 0) - { - int[] rewards = achievement.getLevelUpRewards()[Math.min(level, achievement.getLevelUpRewards().length) - 1]; - gems += rewards[0]; - crowns += rewards[1]; - xp += rewards[2]; - } - - return new int[] {gems, crowns, xp}; - } - - private String getRewardsString(Player player, int[] rewards) - { - String reward = ""; - int gems = rewards[0]; - int crowns = rewards[1]; - int xp = rewards[2]; - - if (gems > 0) - { - reward += C.cGreenB + "+" + gems + " Gems "; - } - if (crowns > 0) - { - reward += C.cGoldB + "+" + crowns + " Crowns "; - } - if (xp > 0 && !_taskManager.hasCompletedTask(player, Achievement.GLOBAL_MINEPLEX_LEVEL.getName())) - { - reward += C.cYellowB + "+" + xp + " EXP "; - } - - return reward; - } - - private void rewardPlayer(Player player, Achievement achievement, int[] rewards) - { - int gems = rewards[0]; - int crowns = rewards[1]; - int xp = rewards[2]; - - if (gems > 0) - { - _donationManager.rewardCurrency(GlobalCurrency.GEM, player, achievement.getName(), gems); - } - if (crowns > 0) - { - _donationManager.rewardCrowns(crowns, player); - } - if (xp > 0) - { - _statsManager.incrementStat(player, Achievement.GLOBAL_MINEPLEX_LEVEL.getStats()[0], xp); - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ComplexSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ComplexSummaryComponent.java deleted file mode 100644 index 3507696e..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ComplexSummaryComponent.java +++ /dev/null @@ -1,27 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.List; - -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; - -public class ComplexSummaryComponent extends GameSummaryComponent -{ - - public ComplexSummaryComponent(GameSummaryComponentType type) - { - super(type, null); - } - - @Override - public String getMainText(Object data) - { - return null; - } - - @Override - public List getHoverText(Object data) - { - return null; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ExperienceSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ExperienceSummaryComponent.java deleted file mode 100644 index ea4db4fc..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ExperienceSummaryComponent.java +++ /dev/null @@ -1,76 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -import org.bukkit.entity.Player; - -import mineplex.core.achievement.AchievementData; -import mineplex.core.achievement.AchievementLog; -import mineplex.core.common.Pair; -import mineplex.core.common.util.C; - -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; -import nautilus.game.arcade.stats.ExperienceStatTracker; - -public class ExperienceSummaryComponent extends GameSummaryComponent> -{ - - public ExperienceSummaryComponent(Function> getFunction) - { - this(GameSummaryComponentType.EXPERIENCE, getFunction); - } - - public ExperienceSummaryComponent(GameSummaryComponentType type, Function> getFunction) - { - super(type, getFunction); - } - - @Override - public String getMainText(Pair data) - { - if (data.getLeft() == null) - { - return null; - } - - return C.cGray + "+" + C.cYellow + data.getLeft().Amount + C.cGray + " Experience" + (ExperienceStatTracker.DOUBLE_EXP ? C.cGoldB + " DOUBLE EXP" : ""); - } - - @Override - public List getHoverText(Pair data) - { - AchievementData achievementData = data.getRight(); - - if (achievementData == null) - { - return null; - } - - List text = new ArrayList<>(2); - - text.add(C.cGray + "You are level " + C.cGreen + achievementData.getLevel()); - - if (data.getRight().getExpRemainder() > 0) - { - text.add(C.cYellow + (achievementData.getExpNextLevel() - achievementData.getExpRemainder()) + " EXP " + C.cGray + "until next level"); - } - - return text; - } - - @Override - public boolean sendMessage(Player player) - { - boolean sent = super.sendMessage(player); - - if (!(this instanceof LevelUpSummaryComponent)) - { - sendBlank(player); - } - - return sent; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/GemSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/GemSummaryComponent.java deleted file mode 100644 index 047f815d..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/GemSummaryComponent.java +++ /dev/null @@ -1,51 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; - -import org.bukkit.entity.Player; - -import mineplex.core.common.util.C; - -import nautilus.game.arcade.game.GemData; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; - -public class GemSummaryComponent extends GameSummaryComponent> -{ - - private final String _colour; - private final String _currency; - - public GemSummaryComponent(Function> getFunction, String colour, String currency) - { - super(GameSummaryComponentType.GEMS, getFunction); - - _colour = colour; - _currency = currency; - } - - @Override - public String getMainText(Map data) - { - AtomicInteger totalGems = new AtomicInteger(); - - data.values().forEach(gemData -> totalGems.getAndAdd((int) gemData.Gems)); - - return C.cGray + "+" + _colour + totalGems.get() + C.cGray + " " + _currency; - } - - @Override - public List getHoverText(Map data) - { - List text = new ArrayList<>(); - - data.forEach((reason, gemData) -> text.add(C.cGray + "+" + _colour + (int) gemData.Gems + C.cGray + " for " + C.cYellow + (gemData.Amount > 0 ? gemData.Amount + " " : "") + reason)); - - return text; - } - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/KitSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/KitSummaryComponent.java deleted file mode 100644 index 318bd065..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/KitSummaryComponent.java +++ /dev/null @@ -1,109 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.Optional; -import java.util.concurrent.atomic.AtomicInteger; - -import org.bukkit.entity.Player; - -import mineplex.core.common.jsonchat.HoverEvent; -import mineplex.core.common.jsonchat.JsonMessage; -import mineplex.core.common.util.C; -import mineplex.core.game.MineplexGameManager; -import mineplex.core.game.kit.GameKit; -import mineplex.core.game.kit.upgrade.KitStat; -import mineplex.core.game.kit.upgrade.KitStatLog; -import mineplex.core.game.kit.upgrade.LinearUpgradeTree; -import mineplex.core.game.kit.upgrade.UpgradeTree; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; - -public class KitSummaryComponent extends ComplexSummaryComponent -{ - - private final ArcadeManager _manager; - - public KitSummaryComponent(ArcadeManager manager) - { - super(GameSummaryComponentType.KIT); - - _manager = manager; - } - - @Override - public boolean sendMessage(Player player) - { - AtomicInteger progressFor = new AtomicInteger(); - StringBuilder hoverTextBuilder = new StringBuilder(100); - - MineplexGameManager manager = _manager.getMineplexGameManager(); - KitStatLog statLog = manager.getKitStatLog().remove(player); - - if (statLog == null) - { - return false; - } - - int xpGained = statLog.getExperienceEarned(); - int kitXP = xpGained / statLog.getKitsUsed().size(); - - for (GameKit kit : statLog.getKitsUsed()) - { - Optional optional = kit.getUpgradeTree(); - - if (!optional.isPresent() || !(optional.get() instanceof LinearUpgradeTree)) - { - continue; - } - - int currentXp = manager.getKitStat(player, kit, KitStat.XP); - int level = LinearUpgradeTree.getLevel(currentXp); - - if (level >= 100) - { - continue; - } - - int newExp = currentXp + kitXP; - int newLevel = LinearUpgradeTree.getLevel(newExp); - - if (newLevel != level) - { - newExp = LinearUpgradeTree.getTotalXpForLevel(level); - newLevel = level + 1; - - new JsonMessage(C.cPurpleB + "Kit Level Up! " + C.cGray + kit.getDisplayName() + " " + C.cWhite + level + " " + C.cGray + DOUBLE_ARROW + " " + C.cWhite + newLevel) - .hover(HoverEvent.SHOW_TEXT, getHoverText(kit, newLevel, LinearUpgradeTree.getXpForLevel(newLevel))) - .sendToPlayer(player); - - manager.setKitStat(player, kit, KitStat.XP, newExp); - } - else - { - hoverTextBuilder.append("\n").append(getHoverText(kit, level, LinearUpgradeTree.getTotalXpForLevel(level) - newExp)); - - progressFor.getAndIncrement(); - - manager.incrementKitStat(player, kit, KitStat.XP, kitXP); - } - } - - if (progressFor.get() == 0) - { - return false; - } - - new JsonMessage(C.cGray + "Progress for " + C.cYellow + progressFor.get() + " Kit" + (progressFor.get() == 1 ? "" : "s")) - .hover(HoverEvent.SHOW_TEXT, hoverTextBuilder.toString().substring(1)) - .sendToPlayer(player); - - sendBlank(player); - return true; - } - - private String getHoverText(GameKit kit, int level, int difference) - { - return C.cGray + "Your " + C.cYellow + kit.getDisplayName() + C.cGray + " is level " + C.cGreen + level + "\n" + - C.cYellow + difference + " EXP " + C.cGray + "until next level"; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/LevelUpSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/LevelUpSummaryComponent.java deleted file mode 100644 index 23bacd98..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/LevelUpSummaryComponent.java +++ /dev/null @@ -1,35 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.function.Function; - -import org.bukkit.entity.Player; - -import mineplex.core.achievement.Achievement; -import mineplex.core.achievement.AchievementData; -import mineplex.core.achievement.AchievementLog; -import mineplex.core.common.Pair; -import mineplex.core.common.util.C; - -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; - -public class LevelUpSummaryComponent extends ExperienceSummaryComponent -{ - - public LevelUpSummaryComponent(Function> getFunction) - { - super(GameSummaryComponentType.LEVEL_UP, getFunction); - } - - @Override - public String getMainText(Pair data) - { - if (data.getLeft() == null || !data.getLeft().LevelUp) - { - return null; - } - - int level = data.getRight().getLevel(); - - return C.cPurpleB + "Level Up! " + Achievement.getExperienceString(level - 1) + C.cGray + " " + DOUBLE_ARROW + " " + Achievement.getExperienceString(level); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ShardSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ShardSummaryComponent.java deleted file mode 100644 index 93148cb7..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/gamesummary/components/ShardSummaryComponent.java +++ /dev/null @@ -1,110 +0,0 @@ -package nautilus.game.arcade.game.modules.gamesummary.components; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -import org.bukkit.entity.Player; - -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.boosters.Booster; -import mineplex.core.common.Pair; -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; -import nautilus.game.arcade.managers.GameRewardManager.Perm; - -public class ShardSummaryComponent extends GameSummaryComponent> -{ - - private final ArcadeManager _manager; - - public ShardSummaryComponent(ArcadeManager manager, Function> getFunction) - { - super(GameSummaryComponentType.SHARDS, getFunction); - - _manager = manager; - } - - @Override - public String getMainText(Pair data) - { - Game game = _manager.GetGame(); - Player player = data.getLeft(); - final int baseShards = data.getRight(); - int totalShards = baseShards; - double extraMult = 0; - - for (Perm shardMultPerm : Perm.values()) - { - if (_manager.GetClients().Get(player).hasPermission(shardMultPerm)) - { - extraMult += 0.5; - } - } - - if (extraMult > 0) - { - totalShards += ((int) (extraMult * baseShards)); - } - - Booster booster = _manager.getBoosterManager().getActiveBooster(); - - if (game.GemBoosterEnabled && booster != null) - { - double multiplier = booster.getMultiplier() - 1; - totalShards += (int) (multiplier * baseShards); - } - - return C.cGray + "+" + C.cAqua + totalShards + C.cGray + " Shards"; - } - - @Override - public List getHoverText(Pair data) - { - List text = new ArrayList<>(); - Game game = _manager.GetGame(); - Player player = data.getLeft(); - final int baseShards = data.getRight(); - double extraMult = 0; - - PermissionGroup group = _manager.GetClients().Get(player).getPrimaryGroup(); - - for (Perm shardMultPerm : Perm.values()) - { - if (_manager.GetClients().Get(player).hasPermission(shardMultPerm)) - { - extraMult += 0.5; - } - } - - text.add(get(baseShards, "Earning " + baseShards + " Game Gems")); - - if (extraMult > 0) - { - int extraShards = ((int) (extraMult * baseShards)); - - text.add(get(extraShards, group.getDisplay(true, true, true, true) + C.cYellow + " Rank " + C.cAqua + "+" + Math.round((extraMult * 100)) + "%")); - } - - Booster booster = _manager.getBoosterManager().getActiveBooster(); - if (game.GemBoosterEnabled && booster != null) - { - double multiplier = booster.getMultiplier() - 1; - int extraShards = ((int) (multiplier * baseShards)); - - text.add(get(extraShards, booster.getPlayerName() + "'s" + F.elem(" Game Amplifier" + C.cAqua + " +" + Math.round((multiplier * 100)) + "%"))); - } - - return text; - } - - private String get(int shards, String reason) - { - return C.cGray + "+" + C.cAqua + shards + C.cGray + " for " + C.cYellow + reason; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/Generator.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/Generator.java deleted file mode 100644 index 1aab4829..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/Generator.java +++ /dev/null @@ -1,131 +0,0 @@ -package nautilus.game.arcade.game.modules.generator; - -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilTime; - -public class Generator -{ - - private static final int COLLECT_RADIUS = 2; - private static final float ROTATION_DELTA_YAW = 10; - - private final GeneratorType _type; - private final Location _location; - private final Block _block; - - private ArmorStand _holder; - private long _lastCollect; - private boolean _colourTick = true; - - public Generator(GeneratorType type, Location location) - { - _type = type; - _location = location.clone().subtract(0, 0.5, 0); - _block = location.getBlock().getRelative(BlockFace.DOWN); - } - - public void checkCollect() - { - if (_holder == null) - { - return; - } - - List nearby = UtilPlayer.getNearby(_location, COLLECT_RADIUS); - - if (nearby.isEmpty()) - { - return; - } - - Player player = nearby.get(0); - _type.collect(this, player); - _holder.remove(); - _holder = null; - setLastCollect(); - UtilServer.CallEvent(new GeneratorCollectEvent(player, this)); - } - - public void checkSpawn() - { - if (_holder != null || !UtilTime.elapsed(_lastCollect, _type.getSpawnRate())) - { - return; - } - - _holder = _type.spawnHolder(this); - } - - public void animateHolder() - { - if (_holder == null) - { - return; - } - - Location location = _holder.getLocation(); - - ((CraftEntity) _holder).getHandle().setPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw() + ROTATION_DELTA_YAW, location.getPitch()); - } - - public void updateName() - { - if (_holder == null) - { - return; - } - - if (!_holder.isCustomNameVisible()) - { - _holder.setCustomNameVisible(true); - } - - if (_type.isFlashName()) - { - _colourTick = !_colourTick; - } - - _holder.setCustomName((_colourTick ? _type.getColour() + C.Bold : C.cWhiteB) + _type.getName()); - } - - public GeneratorType getType() - { - return _type; - } - - public ArmorStand getHolder() - { - return _holder; - } - - public Location getLocation() - { - return _location; - } - - public Block getBlock() - { - return _block; - } - - public void setLastCollect() - { - _lastCollect = System.currentTimeMillis(); - } - - public long getTimeUtilSpawn() - { - return _lastCollect + _type.getSpawnRate() - System.currentTimeMillis(); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorCollectEvent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorCollectEvent.java deleted file mode 100644 index aa13fe20..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorCollectEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -package nautilus.game.arcade.game.modules.generator; - -import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; - -public class GeneratorCollectEvent extends PlayerEvent -{ - - private static final HandlerList HANDLER_LIST = new HandlerList(); - - private final Generator _generator; - - public GeneratorCollectEvent(Player who, Generator generator) - { - super(who); - - _generator = generator; - } - - public Generator getGenerator() - { - return _generator; - } - - public static HandlerList getHandlerList() - { - return HANDLER_LIST; - } - - @Override - public HandlerList getHandlers() - { - return getHandlerList(); - } - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorModule.java deleted file mode 100644 index ff0c1b58..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorModule.java +++ /dev/null @@ -1,145 +0,0 @@ -package nautilus.game.arcade.game.modules.generator; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.block.Block; -import org.bukkit.event.EventHandler; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.player.PlayerArmorStandManipulateEvent; - -import mineplex.core.common.util.F; -import mineplex.core.mission.MissionTrackerType; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; - -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.missions.GameMissionTracker; - -public class GeneratorModule extends Module -{ - - private final List _generators; - - public GeneratorModule() - { - _generators = new ArrayList<>(); - } - - @Override - protected void setup() - { - getGame().registerMissions(new GameMissionTracker(MissionTrackerType.GAME_GENERATOR_COLLECT, getGame()) - { - @EventHandler - public void generatorCollect(GeneratorCollectEvent event) - { - _manager.incrementProgress(event.getPlayer(), event.getGenerator().getType().getItemStack().getAmount(), _trackerType, getGameType(), null); - } - }); - } - - @Override - public void cleanup() - { - _generators.clear(); - } - - public GeneratorModule addGenerator(Generator generator) - { - _generators.add(generator); - return this; - } - - @EventHandler - public void update(UpdateEvent event) - { - if (!getGame().IsLive()) - { - return; - } - - if (event.getType() == UpdateType.FAST) - { - getGame().CreatureAllowOverride = true; - - for (Generator generator : _generators) - { - generator.checkSpawn(); - generator.checkCollect(); - generator.updateName(); - } - - getGame().CreatureAllowOverride = false; - } - else if (event.getType() == UpdateType.TICK) - { - for (Generator generator : _generators) - { - generator.animateHolder(); - } - } - } - - @EventHandler - public void live(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Live) - { - return; - } - - _generators.forEach(Generator::setLastCollect); - } - - @EventHandler - public void blockBreak(BlockBreakEvent event) - { - Block block = event.getBlock(); - - for (Generator generator : _generators) - { - if (generator.getBlock().equals(block)) - { - event.setCancelled(true); - event.getPlayer().sendMessage(F.main("Game", "You cannot break this block.")); - return; - } - } - } - - @EventHandler - public void armourStandManipulate(PlayerArmorStandManipulateEvent event) - { - for (Generator generator : _generators) - { - if (generator.getHolder() != null && generator.getHolder().equals(event.getRightClicked())) - { - event.setCancelled(true); - return; - } - } - } - - @EventHandler - public void armourStandDamage(CustomDamageEvent event) - { - for (Generator generator : _generators) - { - if (generator.getHolder() != null && generator.getHolder().equals(event.GetDamageeEntity())) - { - event.SetCancelled("Generator Holder"); - return; - } - } - } - - public List getGenerators() - { - return _generators; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorType.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorType.java deleted file mode 100644 index 9b058939..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/generator/GeneratorType.java +++ /dev/null @@ -1,99 +0,0 @@ -package nautilus.game.arcade.game.modules.generator; - -import org.bukkit.ChatColor; -import org.bukkit.Color; -import org.bukkit.FireworkEffect; -import org.bukkit.FireworkEffect.Type; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.MapUtil; -import mineplex.core.common.util.UtilEnt; -import mineplex.core.common.util.UtilFirework; - -public class GeneratorType -{ - - private final ItemStack _itemStack; - private final long _spawnRate; - private final String _name; - private final ChatColor _colour; - private final boolean _flashName; - private final FireworkEffect _effect; - - public GeneratorType(ItemStack itemStack, long spawnRate, String name, ChatColor chatColour, Color bukkitColour, boolean flashName) - { - _itemStack = itemStack; - _spawnRate = spawnRate; - _name = name; - _colour = chatColour; - _flashName = flashName; - _effect = FireworkEffect.builder() - .with(Type.BURST) - .withColor(bukkitColour) - .build(); - } - - final void collect(Generator generator, Player player) - { - playEffect(generator); - MapUtil.QuickChangeBlockAt(generator.getBlock().getLocation(), Material.IRON_BLOCK); - collect(player); - } - - final ArmorStand spawnHolder(Generator generator) - { - Location location = generator.getLocation(); - ArmorStand holder = location.getWorld().spawn(location, ArmorStand.class); - - holder.setGravity(false); - holder.setVisible(false); - holder.setHelmet(_itemStack); - holder.setRemoveWhenFarAway(false); - UtilEnt.setTickWhenFarAway(holder, true); - - playEffect(generator); - MapUtil.QuickChangeBlockAt(generator.getBlock().getLocation(), Material.GOLD_BLOCK); - - return holder; - } - - private void playEffect(Generator generator) - { - Location location = generator.getLocation(); - UtilFirework.playFirework(location, _effect); - } - - public void collect(Player player) - { - player.getInventory().addItem(_itemStack); - } - - public ItemStack getItemStack() - { - return _itemStack; - } - - public String getName() - { - return _name; - } - - public long getSpawnRate() - { - return _spawnRate; - } - - public ChatColor getColour() - { - return _colour; - } - - public boolean isFlashName() - { - return _flashName; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkOverrideLoadCommand.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkOverrideLoadCommand.java deleted file mode 100644 index f0d624fa..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkOverrideLoadCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package nautilus.game.arcade.game.modules.perks; - -import org.bukkit.entity.Player; - -import mineplex.core.command.CommandBase; -import mineplex.core.common.util.F; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.games.smash.SuperSmash.Perm; - -public class PerkOverrideLoadCommand extends CommandBase -{ - - private final PerkSpreadsheetModule _module; - - public PerkOverrideLoadCommand(ArcadeManager manager, PerkSpreadsheetModule module) - { - super(manager, Perm.DEBUG_PERK_COMMANDS, "perkload"); - - _module = module; - } - - @Override - public void Execute(Player caller, String[] args) - { - _module.setup(); - caller.sendMessage(F.main("Game", "Overridden Values:")); - - PerkSpreadsheetModule.getValueOverrideMap().forEach((key, value) -> caller.sendMessage(F.main("Game", F.name(key) + " -> " + F.elem(value) + "."))); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkOverrideValueCommand.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkOverrideValueCommand.java deleted file mode 100644 index d823cd2d..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkOverrideValueCommand.java +++ /dev/null @@ -1,73 +0,0 @@ -package nautilus.game.arcade.game.modules.perks; - -import java.util.ArrayList; -import java.util.List; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import mineplex.core.command.CommandBase; -import mineplex.core.common.util.F; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.games.smash.SuperSmash.Perm; - -public class PerkOverrideValueCommand extends CommandBase -{ - - private final PerkSpreadsheetModule _module; - - public PerkOverrideValueCommand(ArcadeManager manager, PerkSpreadsheetModule module) - { - super(manager, Perm.DEBUG_PERK_COMMANDS, "perkoverride"); - - _module = module; - } - - @Override - public void Execute(Player caller, String[] args) - { - if (args.length < 1) - { - sendUsage(caller); - return; - } - - StringBuilder builder = new StringBuilder(); - - // Ignore the last argument - for (int i = 0; i < args.length - 1; i++) - { - builder.append(args[i]).append(" "); - } - - String key = builder.toString().trim(); - String value = args[args.length - 1]; - - if (!_module.getDataMap().containsKey(key)) - { - caller.sendMessage(F.main("Game", "That is not a valid key.")); - return; - } - else if (value.equalsIgnoreCase("clear")) - { - PerkSpreadsheetModule.getValueOverrideMap().remove(key); - caller.sendMessage(F.main("Game", "Reset the perk variable " + F.name(key) + " to it's default value.")); - return; - } - - PerkSpreadsheetModule.getValueOverrideMap().put(key, value); - caller.sendMessage(F.main("Game", "Overrode the perk variable " + F.name(key) + " with value " + F.elem(value) + ".")); - } - - private void sendUsage(Player caller) - { - caller.sendMessage(F.main("Game", "/" + _aliasUsed + " ")); - } - - @Override - public List onTabComplete(CommandSender sender, String commandLabel, String[] args) - { - return new ArrayList<>(_module.getDataMap().keySet()); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkSpreadsheetModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkSpreadsheetModule.java deleted file mode 100644 index 065c9fba..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/perks/PerkSpreadsheetModule.java +++ /dev/null @@ -1,179 +0,0 @@ -package nautilus.game.arcade.game.modules.perks; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import mineplex.core.command.CommandBase; -import mineplex.core.command.CommandCenter; -import mineplex.core.common.Pair; -import mineplex.core.common.util.F; -import mineplex.core.google.GoogleSheetsManager; -import mineplex.core.google.SheetObjectDeserialiser; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.kit.Perk; - -public class PerkSpreadsheetModule extends Module -{ - - private static final SheetObjectDeserialiser> DESERIALISER = values -> Pair.create(values[0], values.length == 1 ? "" : values[1]); - private static final Map VALUE_OVERRIDE_MAP = new HashMap<>(); - static Map getValueOverrideMap() - { - return VALUE_OVERRIDE_MAP; - } - - private final String _fileName; - private final Map _dataMap; - private boolean _initialised; - - private CommandBase _valueCommand; - private CommandBase _loadCommand; - - public PerkSpreadsheetModule(String fileName) - { - _fileName = fileName; - _dataMap = new HashMap<>(); - } - - @Override - public void setup() - { - if (!_initialised) - { - _initialised = true; - - _valueCommand = new PerkOverrideValueCommand(getGame().getArcadeManager(), this); - _loadCommand = new PerkOverrideLoadCommand(getGame().getArcadeManager(), this); - getGame().getArcadeManager().addCommand(_valueCommand); - getGame().getArcadeManager().addCommand(_loadCommand); - } - - // File Name must not be null - Objects.requireNonNull(_fileName); - - // Make sure this is clear - _dataMap.clear(); - - GoogleSheetsManager manager = getGame().getArcadeManager().getSheetsManager(); - Map>> map = manager.getSheetData(_fileName); - - for (Map.Entry>> entry : map.entrySet()) - { - String key = entry.getKey(); - List> value = entry.getValue(); - - Kit kit = getFromName(key); - - if (kit == null) - { - continue; - } - - Perk currentPerk = null; - - for (List rows : value) - { - try - { - Pair pair = DESERIALISER.deserialise(rows.toArray(new String[0])); - - Perk perk = getFromName(kit, pair.getLeft()); - - if (perk != null) - { - currentPerk = perk; - continue; - } - - if (currentPerk != null) - { - String id = getKey(kit, currentPerk, pair.getLeft()); - _dataMap.put(id, pair.getRight()); - } - } - catch (Exception e) - { - // Continue the loop - } - } - } - - for (Kit kit : getGame().GetKits()) - { - for (Perk perk : kit.GetPerks()) - { - try - { - perk.setSpreadsheet(this); - } - catch (Exception e) - { - getGame().Announce(F.main("Game", "An error occurred at Kit " + F.name(kit.GetName()) + ", Perk " + F.name(perk.GetName()) + "."), false); - return; - } - } - } - } - - @Override - public void cleanup() - { - _dataMap.clear(); - CommandCenter.Instance.removeCommand(_valueCommand); - CommandCenter.Instance.removeCommand(_loadCommand); - } - - private Kit getFromName(String name) - { - for (Kit kit : getGame().GetKits()) - { - if (kit.GetName().equalsIgnoreCase(name)) - { - return kit; - } - } - - return null; - } - - private Perk getFromName(Kit kit, String name) - { - for (Perk perk : kit.GetPerks()) - { - if (perk.GetName().equalsIgnoreCase(name)) - { - return perk; - } - } - - return null; - } - - public String getKey(Kit kit, Perk perk, String value) - { - return kit.GetName() + "." + perk.GetName() + "." + value; - } - - public String getValue(String key) - { - String overrideValue = VALUE_OVERRIDE_MAP.get(key); - - if (overrideValue != null) - { - return overrideValue; - } - - return _dataMap.get(key); - } - - Map getDataMap() - { - return _dataMap; - } - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/rejoin/PlayerRejoinGameEvent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/rejoin/PlayerRejoinGameEvent.java deleted file mode 100644 index 2c614fc2..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/rejoin/PlayerRejoinGameEvent.java +++ /dev/null @@ -1,53 +0,0 @@ -package nautilus.game.arcade.game.modules.rejoin; - -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; - -import nautilus.game.arcade.game.modules.rejoin.RejoinModule.PlayerGameInfo; - -public class PlayerRejoinGameEvent extends PlayerEvent implements Cancellable -{ - - private static final HandlerList HANDLER_LIST = new HandlerList(); - - public static HandlerList getHandlerList() - { - return HANDLER_LIST; - } - - private final PlayerGameInfo _playerGameInfo; - - private boolean _cancelled; - - PlayerRejoinGameEvent(Player who, PlayerGameInfo playerGameInfo) - { - super(who); - - _playerGameInfo = playerGameInfo; - } - - public PlayerGameInfo getPlayerGameInfo() - { - return _playerGameInfo; - } - - @Override - public void setCancelled(boolean cancelled) - { - _cancelled = cancelled; - } - - @Override - public boolean isCancelled() - { - return _cancelled; - } - - @Override - public HandlerList getHandlers() - { - return HANDLER_LIST; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/rejoin/RejoinModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/rejoin/RejoinModule.java deleted file mode 100644 index f938ae5e..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/rejoin/RejoinModule.java +++ /dev/null @@ -1,267 +0,0 @@ -package nautilus.game.arcade.game.modules.rejoin; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.common.util.UtilServer; -import mineplex.core.game.rejoin.GameRejoinManager; -import mineplex.core.portal.events.ServerTransferEvent; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.kit.Kit; - -public class RejoinModule extends Module -{ - - private final GameRejoinManager _manager; - private final Map _rejoinData; - private final Set _disallow; - - private boolean _saveInventory; - - public RejoinModule(ArcadeManager manager) - { - _manager = new GameRejoinManager(manager); - _rejoinData = new HashMap<>(); - _disallow = new HashSet<>(); - } - - @Override - protected void setup() - { - getGame().QuitOut = false; - } - - @Override - public void cleanup() - { - _rejoinData.clear(); - _disallow.clear(); - UtilServer.Unregister(_manager); - } - - public RejoinModule setSaveInventory(boolean saveInventory) - { - _saveInventory = saveInventory; - return this; - } - - public void disableRejoining() - { - getGame().QuitOut = true; - _rejoinData.clear(); - _manager.searchToRejoin(); - } - - @EventHandler - public void playerKick(PlayerKickEvent event) - { - if (!isEnabled()) - { - return; - } - - _disallow.add(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void playerTransfer(ServerTransferEvent event) - { - if (!isEnabled()) - { - return; - } - - _disallow.add(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.LOW) - public void playerQuit(PlayerQuitEvent event) - { - if (!isEnabled()) - { - return; - } - - Player player = event.getPlayer(); - - if (_disallow.remove(player) || player.isDead() || !player.getWorld().equals(getGame().WorldData.World)) - { - return; - } - - GameTeam team = getGame().GetTeam(player); - - if (team == null || !team.IsAlive(player)) - { - return; - } - - PlayerGameInfo data; - - if (_saveInventory) - { - data = new PlayerGameInfo(player.getHealth(), player.getInventory().getContents(), player.getInventory().getArmorContents(), getGame().GetKit(player), team); - } - else - { - data = new PlayerGameInfo(player.getHealth(), getGame().GetKit(player), team); - } - - _rejoinData.put(player.getUniqueId(), data); - - team.RemovePlayer(player); - - // For MPS, allow them to rejoin but don't bother sending them the message - if (!getGame().getArcadeManager().GetGameHostManager().isPrivateServer()) - { - _manager.saveRejoinData(player, getGame().GetType().getGameId()); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - public void playerQuitMonitor(PlayerQuitEvent event) - { - _disallow.remove(event.getPlayer()); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void playerLogin(PlayerLoginEvent event) - { - if (!isEnabled() || event.getResult() != Result.ALLOWED) - { - return; - } - - Player player = event.getPlayer(); - PlayerGameInfo info = _rejoinData.get(player.getUniqueId()); - - if (info == null || getGame().getArcadeManager().isVanished(player)) - { - return; - } - - PlayerRejoinGameEvent rejoinEvent = new PlayerRejoinGameEvent(player, info); - UtilServer.CallEvent(rejoinEvent); - - if (rejoinEvent.isCancelled()) - { - info._cancelled = true; - return; - } - - if (info.getTeam() != null) - { - info.getTeam().AddPlayer(player, true); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - public void playerJoin(PlayerJoinEvent event) - { - if (!isEnabled()) - { - return; - } - - Player player = event.getPlayer(); - PlayerGameInfo info = _rejoinData.remove(player.getUniqueId()); - - if (info == null || info.isCancelled() || getGame().getArcadeManager().isVanished(player)) - { - return; - } - - if (info.getKit() != null) - { - getGame().SetKit(player, info.getKit(), false); - getGame().ValidateKit(player, info.getTeam()); - } - - player.setHealth(Math.min(info.getHealth(), player.getHealth())); - - if (_saveInventory) - { - player.getInventory().setArmorContents(info.getInventoryArmour()); - player.getInventory().setContents(info.getInventoryContents()); - } - } - - private boolean isEnabled() - { - return getGame().InProgress() && !getGame().QuitOut; - } - - public class PlayerGameInfo - { - private final double _health; - private final ItemStack[] _inventoryContents, _inventoryArmour; - private final Kit _kit; - private GameTeam _team; - private boolean _cancelled; - - PlayerGameInfo(double health, Kit kit, GameTeam team) - { - this(health, null, null, kit, team); - } - - PlayerGameInfo(double health, ItemStack[] inventoryContents, ItemStack[] inventoryArmour, Kit kit, GameTeam team) - { - _health = health; - _inventoryContents = inventoryContents; - _inventoryArmour = inventoryArmour; - _kit = kit; - _team = team; - } - - public double getHealth() - { - return _health; - } - - public ItemStack[] getInventoryContents() - { - return _inventoryContents; - } - - public ItemStack[] getInventoryArmour() - { - return _inventoryArmour; - } - - public Kit getKit() - { - return _kit; - } - - public void setTeam(GameTeam team) - { - _team = team; - } - - public GameTeam getTeam() - { - return _team; - } - - public boolean isCancelled() - { - return _cancelled; - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/winstreak/WinStreakModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/winstreak/WinStreakModule.java deleted file mode 100644 index ef9587d9..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/winstreak/WinStreakModule.java +++ /dev/null @@ -1,127 +0,0 @@ -package nautilus.game.arcade.game.modules.winstreak; - -import java.util.List; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerQuitEvent; - -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilServer; -import mineplex.core.game.GameDisplay; -import mineplex.core.game.winstreaks.WinStreakManager; -import mineplex.core.stats.PlayerStats; -import mineplex.core.stats.StatsManager; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryModule; - -public class WinStreakModule extends Module -{ - - public static final String BEST_STREAK_STAT = "BestWinStreak"; - private static final String SCRAMBLE_TEXT = C.cGold + C.Scramble + "!"; - static final String BEST_STREAK_TEXT = SCRAMBLE_TEXT + C.cGreenB + " NEW BEST STREAK " + SCRAMBLE_TEXT; - - @Override - protected void setup() - { - getGame().getModule(GameSummaryModule.class) - .addComponent(new WinStreakSummaryComponent(getGame().getArcadeManager())); - } - - @EventHandler(priority = EventPriority.LOW) - public void gameEnd(GameStateChangeEvent event) - { - if (event.GetState() != GameState.End) - { - return; - } - - List winners = getGame().getWinners(); - - if (winners == null) - { - return; - } - - winners.forEach(this::incrementStreak); - - for (Player player : UtilServer.getPlayersCollection()) - { - if (player.isOnline() && !winners.contains(player)) - { - removeStreak(player); - } - } - } - - @EventHandler(priority = EventPriority.LOW) - public void playerQuit(PlayerQuitEvent event) - { - if (!getGame().IsLive()) - { - return; - } - - removeStreak(event.getPlayer()); - } - - private void incrementStreak(Player player) - { - ArcadeManager manager = getGame().getArcadeManager(); - - if (!isEnabled(player)) - { - return; - } - - StatsManager statsManager = manager.GetStatsManager(); - PlayerStats stats = statsManager.Get(player); - WinStreakManager winStreakManager = manager.getWinStreakManager(); - GameDisplay display = getGame().GetType().getDisplay(); - - String bestStreakStat = getStat(BEST_STREAK_STAT); - int streak = manager.getWinStreakManager().getCurrentStreak(player, display); - long bestStreak = stats.getStat(bestStreakStat); - - // This can happen due to when stats are saved. - // To ensure bestStreak doesn't fall behind streak we increment the difference here and then - // never incremented due to the next if statement. - if (bestStreak < streak) - { - statsManager.incrementStat(player, bestStreakStat, streak - bestStreak); - } - - if (streak == bestStreak) - { - statsManager.incrementStat(player, bestStreakStat, 1); - } - - winStreakManager.incrementWinStreak(player, display); - } - - private void removeStreak(Player player) - { - if (!isEnabled(player)) - { - return; - } - - getGame().getArcadeManager().getWinStreakManager().removeWinStreak(player, getGame().GetType().getDisplay()); - } - - private boolean isEnabled(Player player) - { - return getGame().getArcadeManager().IsRewardStats() && getGame().isAllowingGameStats() && getGame().getArcadeManager().hasBeenPlaying(player); - } - - private String getStat(String stat) - { - return getGame().GetName() + "." + stat; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/winstreak/WinStreakSummaryComponent.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/winstreak/WinStreakSummaryComponent.java deleted file mode 100644 index d94a4cda..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/winstreak/WinStreakSummaryComponent.java +++ /dev/null @@ -1,77 +0,0 @@ -package nautilus.game.arcade.game.modules.winstreak; - -import java.util.Arrays; -import java.util.List; - -import org.bukkit.entity.Player; - -import mineplex.core.common.Pair; -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.stats.PlayerStats; -import mineplex.core.stats.StatsManager; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponent; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryComponentType; - -public class WinStreakSummaryComponent extends GameSummaryComponent> -{ - - WinStreakSummaryComponent(ArcadeManager manager) - { - super(GameSummaryComponentType.WIN_STREAK, player -> - { - String game = manager.GetGame().GetName(); - PlayerStats stats = manager.GetStatsManager().Get(player); - - long streak = manager.getWinStreakManager().getCurrentStreak(player, manager.GetGame().GetType().getDisplay()); - long bestStreak = stats.getStat(game + "." + WinStreakModule.BEST_STREAK_STAT); - - return Pair.create(streak, bestStreak); - }); - } - - @Override - public String getMainText(Pair data) - { - long streak = data.getLeft(); - long bestStreak = data.getRight(); - - if (streak == 0) - { - return null; - } - - String text = C.mBody + "Win Streak " + F.count(String.valueOf(streak)) + " "; - - if (streak == bestStreak) - { - text += WinStreakModule.BEST_STREAK_TEXT; - } - - return text; - } - - @Override - public List getHoverText(Pair data) - { - return Arrays.asList( - C.cGray + "Current Streak " + F.count(String.valueOf(data.getLeft())), - C.cGray + "Best Streak " + F.count(String.valueOf(data.getRight())) - ); - } - - @Override - public boolean sendMessage(Player player) - { - boolean sent = super.sendMessage(player); - - if (sent) - { - sendBlank(player); - } - - return sent; - } -} \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/worldmap/WorldMapRenderer.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/worldmap/WorldMapRenderer.java deleted file mode 100644 index 3e1a98ee..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/modules/worldmap/WorldMapRenderer.java +++ /dev/null @@ -1,117 +0,0 @@ -package nautilus.game.arcade.game.modules.worldmap; - -import java.util.concurrent.TimeUnit; - -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.MapRenderer; -import org.bukkit.map.MapView; - -import mineplex.core.recharge.Recharge; - -import nautilus.game.arcade.game.Game; - -public abstract class WorldMapRenderer extends MapRenderer -{ - - private static final long DRAW_RATE = TimeUnit.SECONDS.toMillis(4); - - protected final T _game; - protected WorldMapModule _manager; - - public WorldMapRenderer(T game) - { - _game = game; - } - - public void setManager(WorldMapModule manager) - { - _manager = manager; - } - - @Override - public void render(MapView mapView, MapCanvas canvas, Player player) - { - preRender(player); - - int zoom = _manager.getScale(); - Byte[][] map = _manager.getMap(zoom); - - int centerX = 0; - int centerZ = 0; - - if (Recharge.Instance.use(player, "Draw Map", DRAW_RATE, false, false)) - { - 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; - - color = renderBlock(player, color, mapX, mapZ, blockX, blockZ); - } - else - { - color = (byte) 0; - } - - canvas.setPixel(mapX, mapZ, color); - } - } - - player.sendMap(mapView); - } - - MapCursorCollection cursors = canvas.getCursors(); - - while (cursors.size() > 0) - { - cursors.removeCursor(cursors.getCursor(0)); - } - - renderCursors(canvas, player); - } - - protected void addCursor(MapCanvas canvas, Location location, MapCursor.Type type) - { - MapCursorCollection cursors = canvas.getCursors(); - int zoom = _manager.getScale(); - double mapX = (location.getX() - _manager.getX()) / zoom; - double mapZ = (location.getZ() - _manager.getZ()) / zoom; - - if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64) - { - byte b0 = (byte) (int) Math.min(127, mapX * 2F + 0.5D); - byte b1 = (byte) (int) Math.max(-127, mapZ * 2F + 0.5D); - byte rotation = (byte) (int) (location.getYaw() * 16D / 360D); - - MapCursor cursor = new MapCursor(b0, b1, (byte) (rotation & 0xF), type.getValue(), true); - - cursors.addCursor(cursor); - } - } - - public abstract void renderTick(); - - protected abstract void preRender(Player player); - - protected abstract byte renderBlock(Player player, byte color, int mapX, int mapZ, int blockX, int blockZ); - - protected abstract void renderCursors(MapCanvas canvas, Player player); -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/GameTeamModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/GameTeamModule.java deleted file mode 100644 index ef4f40b1..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/GameTeamModule.java +++ /dev/null @@ -1,264 +0,0 @@ -package nautilus.game.arcade.game.team; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; - -import mineplex.core.Managers; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.friend.FriendManager; -import mineplex.core.party.Party; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.modules.Module; - -public class GameTeamModule extends Module -{ - - private final Map _preferences; - private List _visibleTeams; - - private int _target; - private boolean _prioritisePreferences; - - public GameTeamModule() - { - _preferences = new HashMap<>(); - } - - @Override - public void cleanup() - { - _preferences.clear(); - } - - public GameTeamModule setPlayersPerTeam(int target) - { - _target = target; - return null; - } - - public GameTeamModule setPrioritisePreferences(boolean prioritise) - { - _prioritisePreferences = prioritise; - return null; - } - - @EventHandler(priority = EventPriority.LOWEST) - public void assignTeams(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Prepare) - { - return; - } - - Game game = getGame(); - FriendManager friendManager = Managers.require(FriendManager.class); - boolean autoBalance = game.getArcadeManager().IsTeamBalance(); - - List players = game.getArcadeManager().getValidPlayersForGameStart(); - _visibleTeams = game.GetTeamList().stream() - .filter(GameTeam::GetVisible) - .collect(Collectors.toList()); - - // Only one team. Add all players to that, no need to balance. - if (_visibleTeams.size() == 1) - { - GameTeam team = _visibleTeams.get(0); - - for (Player player : players) - { - game.SetPlayerTeam(player, team, true); - } - - return; - } - - int target; - int total = players.size(); - - if (_target > 0) - { - target = _target; - } - else - { - target = (int) Math.ceil((double) total / _visibleTeams.size()); - } - - // Step 1 - Team Preference (If prioritised) - // This would be set in games where /team is used. - if (_prioritisePreferences) - { - assignPreferences(target, total); - } - - // Step 2 - Parties - // Only worry about parties if autoBalance is on, otherwise we don't care - if (autoBalance) - { - for (Party party : game.getArcadeManager().getPartyManager().getAllParties()) - { - List partyMembers = new ArrayList<>(party.getMembers()); - // Remove party members that are already on a team - partyMembers.removeIf(other -> game.GetTeam(other) != null || !players.contains(other)); - - // Keep going until we just have 1 party member left - while (partyMembers.size() > 1) - { - int partySize = Math.min(partyMembers.size(), target); - GameTeam team = getTeamToJoin(partySize, target, total); - - // Fill the team up as far as it can - for (int i = 0; i < partySize; i++) - { - game.SetPlayerTeam(partyMembers.remove(0), team, true); - } - } - } - } - // No balancing no need to worry about unbalanced teams - else if (_target == 0) - { - target = Integer.MAX_VALUE; - } - - // Step 2 - Team Preferences (Again) - assignPreferences(target, total); - - // Now we worry around everyone else - for (Player player : players) - { - GameTeam playerTeam = game.GetTeam(player); - - // Already in a team - if (playerTeam != null) - { - continue; - } - - // Step 3 - Friends - List friends = friendManager.Get(player).stream() - .filter(friendStatus -> friendStatus.Online) - .map(friendStatus -> UtilPlayer.searchExact(friendStatus.UUID)) - .filter(players::contains) - .collect(Collectors.toList()); - - if (!friends.isEmpty()) - { - friends = new ArrayList<>(friends); - // Remove friends that are already on a team - friends.removeIf(other -> game.GetTeam(other) != null); - // We need to add the player here so that it handles the max team size correctly. - // Don't think about it too much, you just need this otherwise you get 3 players in - // duo games. - friends.add(0, player); - - // Friends operate similarly to parties however we don't need to worry about getting everyone - // on a team with at least one friend since these are friends of the current iterating player. - if (friends.size() > 1) - { - int friendSize = Math.min(friends.size(), target); - GameTeam team = getTeamToJoin(friendSize, target, total); - - // Fill the team up as far as it can - for (int i = 0; i < friendSize; i++) - { - game.SetPlayerTeam(friends.get(i), team, true); - } - - continue; - } - } - - // Step 4 - Emptiest - GameTeam team = getTeamToJoin(1, target, total); - - if (team == null) - { - continue; - } - - game.SetPlayerTeam(player, team, true); - } - } - - private void assignPreferences(int target, int total) - { - _preferences.forEach((player, preference) -> - { - if (getGame().getTeamSelector().canJoinTeam(preference, 1, target, total)) - { - getGame().SetPlayerTeam(player, preference, true); - } - }); - - _preferences.clear(); - } - - public void addPlayerQueue(Player player, GameTeam team) - { - ArcadeManager manager = getGame().getArcadeManager(); - - // No team balancing, we don't care. Just put them on the team. - if (!manager.IsTeamBalance()) - { - getGame().SetPlayerTeam(player, team, true); - return; - } - - GameTeam previous = _preferences.put(player, team); - - if (team.equals(previous)) - { - player.sendMessage(F.main("Game", "You are already queued for " + F.name(team.GetColor() + team.getDisplayName()) + ".")); - } - else - { - player.sendMessage(F.main("Game", "You are now queued for " + F.name(team.GetColor() + team.getDisplayName()) + ".")); - } - } - - private GameTeam getTeamToJoin(int desiredAmount, int target, int total) - { - return getGame().getTeamSelector().getTeamToJoin(_visibleTeams, desiredAmount, target, total); - } - - public void clearQueue(GameTeam team) - { - if (team == null) - { - return; - } - - _preferences.values().removeIf(team::equals); - } - - public int getPlayersQueued(GameTeam team) - { - return (int) _preferences.values().stream() - .filter(team::equals) - .count(); - } - - public Map getPreferences() - { - return _preferences; - } - - public int getPlayersPerTeam() - { - return _target; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/NamedTeamsModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/NamedTeamsModule.java deleted file mode 100644 index 5f400e9e..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/NamedTeamsModule.java +++ /dev/null @@ -1,141 +0,0 @@ -package nautilus.game.arcade.game.team; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.event.EventHandler; - -import mineplex.core.common.util.UtilBlock; - -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.modules.Module; - -public class NamedTeamsModule extends Module -{ - - private boolean _teamPerSpawn; - - private TeamColors _currentColor = TeamColors.first(); - private int _nameIndex; - - @Override - protected void setup() - { - getGame().TeamMode = true; - } - - public NamedTeamsModule setTeamPerSpawn(boolean teamPerSpawn) - { - _teamPerSpawn = teamPerSpawn; - return this; - } - - @EventHandler - public void generateCustomTeams(GameStateChangeEvent event) - { - if (event.GetState() != GameState.Recruit) - { - return; - } - - List spawns = getGame().GetTeamList().get(0).GetSpawns(); - getGame().GetTeamList().clear(); - - if (_teamPerSpawn) - { - for (Location location : spawns) - { - List newSpawns = new ArrayList<>(); - - // Add nearby non block spawns - for (Block block : UtilBlock.getInBoundingBox(location.clone().subtract(2, 0, 2), location.clone().add(2, 0, 2), false)) - { - if (UtilBlock.airFoliage(block) && UtilBlock.airFoliage(block.getRelative(BlockFace.UP))) - { - newSpawns.add(block.getLocation().add(0.5, 0, 0.5)); - } - } - - // Give them a good old shuffle - Collections.shuffle(newSpawns); - - createTeam(newSpawns); - } - } - else - { - int playersPerTeam = getGame().getTeamModule().getPlayersPerTeam(); - int teams = getGame().getArcadeManager().GetPlayerFull() / playersPerTeam; - - for (int i = 0; i < teams; i++) - { - createTeam(spawns); - } - } - } - - private void createTeam(List spawns) - { - // Create the team - GameTeam team = new GameTeam(getGame(), _currentColor._names[_nameIndex], _currentColor._color, spawns, true); - getGame().AddTeam(team); - - _currentColor = _currentColor.next(); - - // If there is no next colour reset and increment name index - if (_currentColor == null) - { - _currentColor = TeamColors.first(); - _nameIndex++; - } - } - - enum TeamColors - { - - YELLOW(ChatColor.YELLOW, new String[]{"Banana", "Mopple", "Custard", "Sponge", "Star", "Giraffe", "Lego", "Light"}), - GREEN(ChatColor.GREEN, new String[]{"Creepers", "Alien", "Seaweed", "Emerald", "Grinch", "Shrub", "Snake", "Leaf"}), - AQUA(ChatColor.AQUA, new String[]{"Diamond", "Ice", "Pool", "Kraken", "Aquatic", "Ocean"}), - RED(ChatColor.RED, new String[]{"Heart", "Tomato", "Ruby", "Jam", "Rose", "Apple", "TNT"}), - GOLD(ChatColor.GOLD, new String[]{"Mango", "Foxes", "Sunset", "Nuggets", "Lion", "Desert", "Gapple"}), - LIGHT_PURPLE(ChatColor.LIGHT_PURPLE, new String[]{"Dream", "Cupcake", "Cake", "Candy", "Unicorn"}), - DARK_BLUE(ChatColor.DARK_BLUE, new String[]{"Squid", "Lapis", "Sharks", "Galaxy", "Empoleon"}), - DARK_RED(ChatColor.DARK_RED, new String[]{"Rose", "Apple", "Twizzler", "Rocket", "Blood"}), - WHITE(ChatColor.WHITE, new String[]{"Ghosts", "Spookies", "Popcorn", "Seagull", "Rice", "Snowman", "Artic"}), - BLUE(ChatColor.BLUE, new String[]{"Sky", "Whale", "Lake", "Birds", "Bluebird", "Piplup"}), - DARK_GREEN(ChatColor.DARK_GREEN, new String[]{"Forest", "Zombies", "Cactus", "Slime", "Toxic", "Poison"}), - DARK_PURPLE(ChatColor.DARK_PURPLE, new String[]{"Amethyst", "Slugs", "Grape", "Witch", "Magic", "Zula"}), - DARK_AQUA(ChatColor.DARK_AQUA, new String[]{"Snorlax", "Aquatic", "Clam", "Fish"}); - - static TeamColors first() - { - return TeamColors.values()[0]; - } - - private final ChatColor _color; - private final String[] _names; - - TeamColors(ChatColor color, String[] names) - { - _color = color; - _names = names; - } - - TeamColors next() - { - if (ordinal() == values().length - 1) - { - return null; - } - - return values()[ordinal() + 1]; - } - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/TeamRequestsModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/TeamRequestsModule.java deleted file mode 100644 index 6dcaf23e..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/TeamRequestsModule.java +++ /dev/null @@ -1,213 +0,0 @@ -package nautilus.game.arcade.game.team; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; - -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.command.CommandBase; -import mineplex.core.command.ICommand; -import mineplex.core.common.jsonchat.ClickEvent; -import mineplex.core.common.jsonchat.HoverEvent; -import mineplex.core.common.jsonchat.JsonMessage; -import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.recharge.Recharge; - -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.modules.Module; - -public class TeamRequestsModule extends Module -{ - - public enum Perm implements Permission - { - TEAM_COMMAND - } - - private final Map _teamRequests; - private ICommand _teamCommand; - - public TeamRequestsModule() - { - _teamRequests = new HashMap<>(); - } - - @Override - protected void setup() - { - _teamCommand = new CommandBase(getGame().getArcadeManager(), Perm.TEAM_COMMAND, "team") - { - - @Override - public void Execute(Player caller, String[] args) - { - if (args.length == 0) - { - caller.sendMessage(F.main("Game", "/team ")); - return; - } - - if (getGame().GetState() != GameState.Recruit) - { - caller.sendMessage(F.main("Game", "You cannot send team requests at this time!")); - return; - } - - //Observer - if (getGame().getArcadeManager().IsObserver(caller)) - { - caller.sendMessage(F.main("Game", "Spectators cannot partake in games.")); - return; - } - - Player target = UtilPlayer.searchOnline(caller, args[0], true); - - if (target == null) - { - return; - } - - if (caller.equals(target)) - { - caller.sendMessage(F.main("Game", "You can't team with yourself!")); - return; - } - - selectTeamMate(caller, target); - } - }; - - PermissionGroup.PLAYER.setPermission(Perm.TEAM_COMMAND, true, true); - getGame().getArcadeManager().addCommand(_teamCommand); - getGame().getTeamModule().setPrioritisePreferences(true); - } - - @Override - public void cleanup() - { - _teamRequests.clear(); - getGame().getArcadeManager().removeCommand(_teamCommand); - } - - @EventHandler(priority = EventPriority.HIGH) - public void teamSelectInteract(PlayerInteractEntityEvent event) - { - if (getGame().GetState() != GameState.Recruit || !(event.getRightClicked() instanceof Player)) - { - return; - } - - Player player = event.getPlayer(); - ItemStack itemStack = player.getItemInHand(); - - if (itemStack != null && itemStack.getType() != Material.AIR) - { - return; - } - else if (getGame().getArcadeManager().IsObserver(player)) - { - UtilPlayer.message(player, F.main("Game", "Spectators cannot partake in games.")); - return; - } - - selectTeamMate(player, (Player) event.getRightClicked()); - } - - private void selectTeamMate(Player player, Player ally) - { - Map preferences = getGame().getTeamModule().getPreferences(); - GameTeam playerTeam = preferences.get(player); - GameTeam allyTeam = preferences.get(ally); - - if (playerTeam != null && playerTeam.equals(allyTeam)) - { - return; - } - - //Accept Invite - if (player.getUniqueId().equals(_teamRequests.get(ally.getUniqueId()))) - { - //Remove Prefs - _teamRequests.remove(player.getUniqueId()); - _teamRequests.remove(ally.getUniqueId()); - - //Inform - player.sendMessage(F.main("Game", "You accepted " + F.name(ally.getName()) + "'s " + F.elem("Team Request") + "!")); - ally.sendMessage(F.main("Game", F.name(player.getName()) + " accepted your " + F.elem("Team Request") + "!")); - - // This ensures there is always a free team - getGame().getTeamModule().clearQueue(playerTeam); - getGame().getTeamModule().clearQueue(allyTeam); - - GameTeam team = getEmptyTeam(); - - preferences.put(player, team); - preferences.put(ally, team); - } - //Send Invite - else - { - //Already on Team with Target - if (playerTeam != null && playerTeam.HasPlayer(ally)) - { - return; - } - - //Inform Player - player.sendMessage(F.main("Game", "You sent a " + F.elem("Team Request") + " to " + F.name(ally.getName()) + "!")); - - //Inform Target - if (Recharge.Instance.use(player, "Team Req " + ally.getName(), 2000, false, false)) - { - ally.sendMessage(F.main("Game", F.name(player.getName()) + " sent you a " + F.elem("Team Request") + "!")); - new JsonMessage(F.main("Game", F.elem(C.Bold + "CLICK HERE") + " to join their team!")) - .hover(HoverEvent.SHOW_TEXT, C.cYellow + "Click to join " + player.getName() + "'s team") - .click(ClickEvent.RUN_COMMAND, "/team " + player.getName()) - .sendToPlayer(ally); - } - - //Add Pref - _teamRequests.put(player.getUniqueId(), ally.getUniqueId()); - } - } - - @EventHandler (priority = EventPriority.LOWEST) - public void teamQuit(PlayerQuitEvent event) - { - if (getGame().GetState() != GameState.Recruit) - { - return; - } - - Player player = event.getPlayer(); - GameTeam team = getGame().GetTeam(player); - - if (team != null) - { - team.DisbandTeam(); - } - - _teamRequests.entrySet().removeIf(entry -> entry.getKey().equals(player.getUniqueId()) || entry.getValue().equals(player.getUniqueId())); - } - - private GameTeam getEmptyTeam() - { - return getGame().GetTeamList().stream() - .filter(team -> getGame().getTeamModule().getPlayersQueued(team) == 0) - .findFirst() - .orElse(null); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/EvenTeamSelector.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/EvenTeamSelector.java deleted file mode 100644 index 0957840f..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/EvenTeamSelector.java +++ /dev/null @@ -1,24 +0,0 @@ -package nautilus.game.arcade.game.team.selectors; - -import java.util.Comparator; -import java.util.List; - -import nautilus.game.arcade.game.GameTeam; - -public class EvenTeamSelector implements TeamSelector -{ - - @Override - public GameTeam getTeamToJoin(List teams, int desiredAmount, int target, int total) - { - return teams.stream() - .min(Comparator.comparingInt(GameTeam::GetSize)) - .orElse(null); - } - - @Override - public boolean canJoinTeam(GameTeam team, int desiredAmount, int target, int total) - { - return team.GetSize() + desiredAmount <= target; - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/FillToSelector.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/FillToSelector.java deleted file mode 100644 index b79a1eef..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/FillToSelector.java +++ /dev/null @@ -1,35 +0,0 @@ -package nautilus.game.arcade.game.team.selectors; - -import java.util.Comparator; -import java.util.List; - -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.GameTeam; - -public class FillToSelector extends EvenTeamSelector -{ - - public FillToSelector(Game game, int amount) - { - game.getTeamModule().setPlayersPerTeam(amount); - } - - @Override - public GameTeam getTeamToJoin(List teams, int desiredAmount, int target, int total) - { - // Get the biggest team that can fit our desired amount - GameTeam primaryChoice = teams.stream() - .filter(team -> canJoinTeam(team, desiredAmount, target, total)) - .max(Comparator.comparingInt(GameTeam::GetSize)) - .orElse(null); - - if (primaryChoice != null) - { - return primaryChoice; - } - - // This would happen if all teams are full and we are overflowing - // Just get the emptiest team. - return super.getTeamToJoin(teams, desiredAmount, target, total); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/RatioSelector.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/RatioSelector.java deleted file mode 100644 index 278f25a8..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/RatioSelector.java +++ /dev/null @@ -1,40 +0,0 @@ -package nautilus.game.arcade.game.team.selectors; - -import java.util.List; -import java.util.stream.Collectors; - -import mineplex.core.common.util.UtilAlg; - -import nautilus.game.arcade.game.GameTeam; - -public class RatioSelector implements TeamSelector -{ - - private final GameTeam _team; - private final double _ratio; - - public RatioSelector(GameTeam team, double ratio) - { - _team = team; - _ratio = ratio; - } - - @Override - public GameTeam getTeamToJoin(List teams, int desiredAmount, int target, int total) - { - if (canJoinTeam(_team, desiredAmount, target, total)) - { - return _team; - } - - return UtilAlg.Random(teams.stream() - .filter(team -> !team.equals(_team)) - .collect(Collectors.toList())); - } - - @Override - public boolean canJoinTeam(GameTeam team, int desiredAmount, int target, int total) - { - return !team.equals(_team) || _team.GetSize() + desiredAmount <= Math.max(_ratio * total, 1); - } -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/TeamSelector.java b/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/TeamSelector.java deleted file mode 100644 index 56eaf0ad..00000000 --- a/Plugins[Modified]/Nautilus.Game.Arcade/game/team/selectors/TeamSelector.java +++ /dev/null @@ -1,14 +0,0 @@ -package nautilus.game.arcade.game.team.selectors; - -import java.util.List; - -import nautilus.game.arcade.game.GameTeam; - -public interface TeamSelector -{ - - GameTeam getTeamToJoin(List teams, int desiredAmount, int target, int total); - - boolean canJoinTeam(GameTeam team, int desiredAmount, int target, int total); - -} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index d05a4f96..179216bb 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -1,15 +1,33 @@ package nautilus.game.arcade; +import java.io.File; + +import mineplex.core.TwitchIntegrationFix; +import net.minecraft.server.v1_8_R3.MinecraftServer; + +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.plugin.ServicePriority; +import org.bukkit.plugin.java.JavaPlugin; +import org.spigotmc.SpigotConfig; + import mineplex.core.CustomTagFix; import mineplex.core.FoodDupeFix; import mineplex.core.PacketsInteractionFix; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; +//import mineplex.core.antihack.AntiHack; +//import mineplex.core.antihack.RelationProvider; +//import mineplex.core.antihack.logging.AntihackLogger; import mineplex.core.aprilfools.AprilFoolsManager; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blood.Blood; import mineplex.core.boosters.BoosterManager; import mineplex.core.chat.Chat; +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; @@ -38,12 +56,15 @@ 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; import mineplex.core.projectile.ProjectileManager; import mineplex.core.punish.Punish; import mineplex.core.recharge.Recharge; +import mineplex.core.report.ReportManager; +import mineplex.core.report.ReportPlugin; import mineplex.core.serverConfig.ServerConfiguration; import mineplex.core.sound.SoundNotifier; import mineplex.core.stats.StatsManager; @@ -51,21 +72,14 @@ 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.velocity.VelocityFix; import mineplex.core.visibility.VisibilityManager; +import mineplex.core.website.WebsiteLinkManager; import mineplex.minecraft.game.core.combat.CombatManager; import mineplex.minecraft.game.core.damage.DamageManager; import nautilus.game.arcade.game.GameServerConfig; -import net.minecraft.server.v1_8_R3.MinecraftServer; -import org.bukkit.Bukkit; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; -import org.spigotmc.SpigotConfig; - -import java.io.File; - import static mineplex.core.Managers.require; public class Arcade extends JavaPlugin @@ -78,7 +92,19 @@ public class Arcade extends JavaPlugin @Override public void onEnable() { - + /* + getServer().getServicesManager().register(RelationProvider.class, (player, target) -> + { + if (target instanceof Player) + { + return _gameManager.canHurt(player, (Player) target); + } + else + { + return target instanceof LivingEntity && _gameManager.GetGame() != null && _gameManager.GetGame().IsLive(); + } + }, this, ServicePriority.Normal); + */ Bukkit.setSpawnRadius(0); //Delete Old Games Folders DeleteFolders(); @@ -122,7 +148,7 @@ public class Arcade extends JavaPlugin Creature creature = new Creature(this); Teleport teleport = new Teleport(this, clientManager); Portal portal = new Portal(); - //new FileUpdater(GenericServer.HUB); + new FileUpdater(GenericServer.HUB); DisguiseManager disguiseManager = require(DisguiseManager.class); @@ -131,6 +157,8 @@ public class Arcade extends JavaPlugin Punish punish = new Punish(this, clientManager); + //require(AntiHack.class); + IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal); StatsManager statsManager = new StatsManager(this, clientManager); EloManager eloManager = new EloManager(this, clientManager); @@ -139,12 +167,10 @@ public class Arcade extends JavaPlugin Chat chat = require(Chat.class); new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, chat); - /* SnapshotManager snapshotManager = new SnapshotManager(this, new SnapshotRepository(serverStatusManager.getCurrentServerName(), getLogger())); ReportManager reportManager = new ReportManager(this, snapshotManager, clientManager, incognito, punish, serverStatusManager.getRegion(), serverStatusManager.getCurrentServerName(), 1); new SnapshotPlugin(this, snapshotManager, clientManager); new ReportPlugin(this, reportManager); - */ BlockRestore blockRestore = require(BlockRestore.class); @@ -170,6 +196,8 @@ public class Arcade extends JavaPlugin PollManager pollManager = new PollManager(this, clientManager, donationManager); _gameManager = new ArcadeManager(this, serverStatusManager, ReadServerConfig(), clientManager, donationManager, damageManager, statsManager, incognito, achievementManager, disguiseManager, creature, teleport, new Blood(this), chat, portal, preferenceManager, inventoryManager, packetHandler, cosmeticManager, projectileManager, petManager, hologramManager, pollManager, npcmanager, customDataManager, punish, eloManager, thankManager, boosterManager); + //require(AntihackLogger.class).registerMetadata(new GameInfoMetadata()); + //new BroadcastManager(this, _gameManager); new MemoryFix(this); @@ -178,8 +206,9 @@ public class Arcade extends JavaPlugin new FoodDupeFix(this); require(TwoFactorAuth.class); - //require(WebsiteLinkManager.class); - + require(WebsiteLinkManager.class); + require(TwitchIntegrationFix.class); + AprilFoolsManager.getInstance(); require(CustomItemFrames.class); @@ -190,7 +219,6 @@ public class Arcade extends JavaPlugin MinecraftServer.getServer().getPropertyManager().setProperty("debug", false); SpigotConfig.debug = false; - } @Override @@ -198,11 +226,7 @@ public class Arcade extends JavaPlugin { for (Player player : UtilServer.getPlayers()) player.kickPlayer("Server Shutdown"); - /* Fast hack for despawning entity and fucked up waiting map */ - _gameManager.GetGame().setGame(GameType.BaconBrawl, null, false); - for(Entity entity : getServer().getWorld("world").getEntities()) { - entity.remove(); - } + if (_gameManager.GetGame() != null) if (_gameManager.GetGame().WorldData != null) _gameManager.GetGame().WorldData.Uninitialize(); diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index a2f7a569..9d32cfe4 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -1,5 +1,42 @@ package nautilus.game.arcade; +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.server.v1_8_R3.EntityLiving; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.scoreboard.Team; +import org.bukkit.util.Vector; + import mineplex.core.Managers; import mineplex.core.MiniPlugin; import mineplex.core.PlayerSelector; @@ -16,7 +53,13 @@ import mineplex.core.boosters.BoosterManager; import mineplex.core.chat.Chat; import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.timing.TimingManager; -import mineplex.core.common.util.*; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilLambda; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.communities.CommunityManager; import mineplex.core.cosmetic.CosmeticManager; import mineplex.core.creature.Creature; @@ -92,9 +135,18 @@ import mineplex.minecraft.game.core.condition.Condition; import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.fire.Fire; + import nautilus.game.arcade.addons.SoupAddon; import nautilus.game.arcade.booster.GameBoosterManager; -import nautilus.game.arcade.command.*; +import nautilus.game.arcade.command.CancelNextGameCommand; +import nautilus.game.arcade.command.GameCommand; +import nautilus.game.arcade.command.GoToNextGameCommand; +import nautilus.game.arcade.command.KitUnlockCommand; +import nautilus.game.arcade.command.MapCommand; +import nautilus.game.arcade.command.ReturnToHubCommand; +import nautilus.game.arcade.command.SpectatorCommand; +import nautilus.game.arcade.command.TauntCommand; +import nautilus.game.arcade.command.TournamentStopCommand; import nautilus.game.arcade.events.GameStateChangeEvent; import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.Game.GameState; @@ -103,36 +155,27 @@ import nautilus.game.arcade.game.GameTeam; import nautilus.game.arcade.game.games.event.EventModule; import nautilus.game.arcade.game.games.minecraftleague.MinecraftLeague; import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.managers.*; +import nautilus.game.arcade.managers.GameAchievementManager; +import nautilus.game.arcade.managers.GameCreationManager; +import nautilus.game.arcade.managers.GameFlagManager; +import nautilus.game.arcade.managers.GameHostManager; +import nautilus.game.arcade.managers.GameLootManager; +import nautilus.game.arcade.managers.GameManager; +import nautilus.game.arcade.managers.GamePlayerManager; +import nautilus.game.arcade.managers.GameRewardManager; +import nautilus.game.arcade.managers.GameSpectatorManager; +import nautilus.game.arcade.managers.GameStatManager; +import nautilus.game.arcade.managers.GameWorldManager; +import nautilus.game.arcade.managers.HubClockManager; +import nautilus.game.arcade.managers.IdleManager; +import nautilus.game.arcade.managers.NextBestGameManager; +import nautilus.game.arcade.managers.ServerUptimeManager; import nautilus.game.arcade.managers.chat.GameChatManager; import nautilus.game.arcade.managers.lobby.LobbyManager; import nautilus.game.arcade.managers.lobby.current.NewGameLobbyManager; import nautilus.game.arcade.managers.lobby.legacy.LegacyGameLobbyManager; import nautilus.game.arcade.managers.voting.Vote; import nautilus.game.arcade.managers.voting.Voteable; -import net.minecraft.server.v1_8_R3.EntityLiving; -import org.bukkit.GameMode; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.*; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.player.*; -import org.bukkit.event.player.PlayerLoginEvent.Result; -import org.bukkit.event.server.ServerListPingEvent; -import org.bukkit.potion.PotionEffect; -import org.bukkit.scoreboard.Team; -import org.bukkit.util.Vector; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; public class ArcadeManager extends MiniPlugin implements IRelation { @@ -210,7 +253,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation private KitProgressionManager _kitProgressionManager; private BoosterManager _boosterManager; private GameSpectatorManager _spectatorManager; - //private ServerUptimeManager _serverUptimeManager; + private ServerUptimeManager _serverUptimeManager; private ScoreboardManager _scoreboardManager; private NextBestGameManager _nextBestGameManager; private TrackManager _trackManager; @@ -335,21 +378,18 @@ public class ArcadeManager extends MiniPlugin implements IRelation _conditionManager, _projectileManager, _disguiseManager, _blockRestore, _fire, new Movement(plugin), teleport, _energy); - /* _classManager = new ClassManager(plugin, clientManager, donationManager, _cosmeticManager.getGadgetManager(), _skillFactory, _itemFactory); _classShopManager = new ClassShopManager(_plugin, _classManager, _skillFactory, _itemFactory, _achievementManager, clientManager); _classShop = new ClassCombatShop(_classShopManager, clientManager, donationManager, false, "Class Shop"); - - */ _eloManager = eloManager; _punishmentManager = punish; _kitProgressionManager = new KitProgressionManager(getPlugin(), donationManager, clientManager); - //_serverUptimeManager = new ServerUptimeManager(this); + _serverUptimeManager = new ServerUptimeManager(this); _missionsManager = require(MissionManager.class); _missionsManager.createNPC(_gameLobbyManager.getMissions()); _missionsManager.setCanIncrement(() -> false); @@ -1734,7 +1774,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation _plugin.getServer().getPluginManager().registerEvents(_classShop, _plugin); } - /* public void disableChampionsModules() { _classManager.setEnabled(false); @@ -1770,7 +1809,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation disableChampionsModules(); } } - */ public boolean isChampionsEnabled() { diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java index 9babb604..337a634e 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java @@ -1,15 +1,20 @@ package nautilus.game.arcade; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + import mineplex.core.common.MinecraftVersion; import mineplex.core.common.Pair; import mineplex.core.game.GameDisplay; import mineplex.core.itemstack.ItemBuilder; + import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.games.alieninvasion.AlienInvasion; import nautilus.game.arcade.game.games.baconbrawl.BaconBrawl; import nautilus.game.arcade.game.games.barbarians.Barbarians; import nautilus.game.arcade.game.games.basketball.Basketball; import nautilus.game.arcade.game.games.battleroyale.BattleRoyaleSolo; +import nautilus.game.arcade.game.games.bossbattles.BossBattles; import nautilus.game.arcade.game.games.bridge.Bridge; import nautilus.game.arcade.game.games.bridge.modes.OverpoweredBridge; import nautilus.game.arcade.game.games.build.Build; @@ -20,6 +25,9 @@ import nautilus.game.arcade.game.games.cakewars.modes.OPCakeWars; import nautilus.game.arcade.game.games.castleassault.CastleAssault; import nautilus.game.arcade.game.games.castleassault.CastleAssaultTDM; import nautilus.game.arcade.game.games.castlesiegenew.CastleSiegeNew; +import nautilus.game.arcade.game.games.champions.ChampionsCTF; +import nautilus.game.arcade.game.games.champions.ChampionsDominate; +import nautilus.game.arcade.game.games.champions.ChampionsTDM; import nautilus.game.arcade.game.games.christmas.Christmas; import nautilus.game.arcade.game.games.christmasnew.ChristmasNew; import nautilus.game.arcade.game.games.deathtag.DeathTag; @@ -79,9 +87,6 @@ import nautilus.game.arcade.game.games.wither.WitherGame; import nautilus.game.arcade.game.games.wizards.Wizards; import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival; import nautilus.game.arcade.managers.voting.Voteable; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import nautilus.game.arcade.game.games.champions.*; public enum GameType implements Voteable { @@ -89,7 +94,7 @@ public enum GameType implements Voteable BaconBrawl(BaconBrawl.class, GameDisplay.BaconBrawl), Barbarians(Barbarians.class, GameDisplay.Barbarians), Basketball(Basketball.class, GameDisplay.Basketball), - BossBattles(nautilus.game.arcade.game.games.bossbattles.BossBattles.class, GameDisplay.BossBattles), + BossBattles(BossBattles.class, GameDisplay.BossBattles), Bridge(Bridge.class, new GameMode[] { new GameMode(OverpoweredBridge.class, "OP Bridges"), diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/anticheatmetadata/GameInfoMetadata.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/anticheatmetadata/GameInfoMetadata.java new file mode 100644 index 00000000..44c88f14 --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/anticheatmetadata/GameInfoMetadata.java @@ -0,0 +1,203 @@ +package nautilus.game.arcade.anticheatmetadata; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import mineplex.core.common.util.UtilServer; + +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.game.Game; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.kit.LinearUpgradeKit; +import nautilus.game.arcade.managers.GameHostManager; +import static mineplex.core.Managers.require; + +public class GameInfoMetadata +{ + private static final String KEY_GAME_INFO = "game-info"; + private static final String KEY_GAME_MAP = "map"; + private static final String KEY_GAME_TYPE = "type"; + private static final String KEY_GAME_MODE = "mode"; + private static final String KEY_CURRENT_STATE = "current-state"; + private static final String KEY_STATE_START_TIME = "current-state-start-time"; + private static final String KEY_JOIN_GAME_TIME = "join-game-time-ms"; + + private static final String KEY_STATE_TIMES = "state-times"; + + private static final String KEY_KIT_INFO = "kit-info"; + private static final String KEY_KIT_NAME = "name"; + private static final String KEY_KIT_LEVEL = "level"; + + private static final String KEY_MPS = "mps"; + private static final String KEY_OWNER = "owner"; + + private static final String KEY_STATS = "stats"; + + private static final String KEY_WINNER = "winner"; + + private final Map _allGames = new HashMap<>(); + private final Map _currentGame = new HashMap<>(); + + private final ArcadeManager _arcadeManager = require(ArcadeManager.class); + + public String getId() + { + return "game-info"; + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + _allGames.put(event.getPlayer().getUniqueId(), new JsonArray()); + + JsonObject currentGame = buildCurrentGame(); + + if (currentGame != null) + { + _currentGame.put(event.getPlayer().getUniqueId(), currentGame); + } + } + + private JsonObject buildCurrentGame() + { + Game game = _arcadeManager.GetGame(); + + if (game == null) + return null; + + JsonObject currentGame = new JsonObject(); + + JsonObject gameInfo = new JsonObject(); + gameInfo.addProperty(KEY_GAME_MAP, game.WorldData.File); + gameInfo.addProperty(KEY_GAME_TYPE, game.GetName()); + gameInfo.addProperty(KEY_GAME_MODE, game.GetMode()); + gameInfo.addProperty(KEY_CURRENT_STATE, game.GetState().name()); + gameInfo.addProperty(KEY_STATE_START_TIME, game.GetStateTime()); + gameInfo.addProperty(KEY_JOIN_GAME_TIME, System.currentTimeMillis()); + + if (_arcadeManager.GetGameHostManager() != null && _arcadeManager.GetGameHostManager().isPrivateServer()) + { + GameHostManager gameHostManager = _arcadeManager.GetGameHostManager(); + + JsonObject mpsInfo = new JsonObject(); + mpsInfo.addProperty(KEY_OWNER, _arcadeManager.GetHost()); + + currentGame.add(KEY_MPS, mpsInfo); + } + + currentGame.add(KEY_GAME_INFO, gameInfo); + + JsonObject stateStartTimes = new JsonObject(); + stateStartTimes.addProperty(game.GetState().name(), game.GetStateTime()); + + currentGame.add(KEY_STATE_TIMES, stateStartTimes); + + return currentGame; + } + + @EventHandler + public void onStateChange(GameStateChangeEvent event) + { + if (event.GetState() == Game.GameState.Recruit) + { + for (Player player : UtilServer.getPlayersCollection()) + { + if (!_currentGame.containsKey(player.getUniqueId())) + { + _currentGame.put(player.getUniqueId(), buildCurrentGame()); + } + } + } + + if (event.GetState() == Game.GameState.Live) + { + _currentGame.forEach((id, obj) -> + { + Player player = Bukkit.getPlayer(id); + if (player != null) + { + Kit kit = event.GetGame().GetKit(player); + if (kit != null) + { + JsonObject kitInfo = new JsonObject(); + kitInfo.addProperty(KEY_KIT_NAME, kit.GetName()); + + if (kit instanceof LinearUpgradeKit) + { + LinearUpgradeKit pk = (LinearUpgradeKit) kit; + kitInfo.addProperty(KEY_KIT_LEVEL, pk.getLevel(player)); + } + + obj.add(KEY_KIT_INFO, kitInfo); + } + } + }); + + } + + _currentGame.values().forEach(obj -> + { + obj.get(KEY_STATE_TIMES).getAsJsonObject().addProperty(event.GetState().name(), System.currentTimeMillis()); + }); + + if (event.GetState() == Game.GameState.Dead) + { + new ArrayList<>(_currentGame.keySet()).forEach(ent -> archivePlayer(event.GetGame(), ent)); + } + } + + private void archivePlayer(Game game, UUID uuid) + { + JsonObject gameObj = _currentGame.remove(uuid); + + if (gameObj == null) + return; + + _allGames.get(uuid).add(gameObj); + + if (game == null) + return; + + Player player = Bukkit.getPlayer(uuid); + + if (player == null) + return; + + Map stats = game.GetStats().get(player); + + if (stats != null) + { + JsonObject statsObject = new JsonObject(); + stats.forEach(statsObject::addProperty); + + gameObj.add(KEY_STATS, statsObject); + } + + gameObj.addProperty(KEY_WINNER, game.Winner); + } + + public JsonElement build(UUID player) + { + archivePlayer(_arcadeManager.GetGame(), player); + + return _allGames.get(player); + } + + public void remove(UUID player) + { + _allGames.remove(player); + _currentGame.remove(player); + } +} diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java index c2c8f83f..26f26c31 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java @@ -1,61 +1,29 @@ package nautilus.game.arcade.game; -import com.mojang.authlib.GameProfile; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.arcadeevents.CoreGameStartEvent; -import mineplex.core.arcadeevents.CoreGameStopEvent; -import mineplex.core.command.CommandCenter; -import mineplex.core.common.util.*; -import mineplex.core.disguise.disguises.DisguisePlayer; -import mineplex.core.elo.EloPlayer; -import mineplex.core.elo.EloTeam; -import mineplex.core.game.MineplexGameManager; -import mineplex.core.game.kit.KitAvailability; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.lifetimes.Lifetimed; -import mineplex.core.lifetimes.ListenerComponent; -import mineplex.core.lifetimes.PhasedLifetime; -import mineplex.core.mission.MissionTracker; -import mineplex.core.packethandler.IPacketHandler; -import mineplex.core.preferences.Preference; -import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.core.utils.UtilGameProfile; -import mineplex.minecraft.game.classcombat.event.ClassCombatCreatureAllowSpawnEvent; -import mineplex.minecraft.game.core.combat.DeathMessageType; -import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; -import nautilus.game.arcade.ArcadeFormat; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.events.PlayerGameRespawnEvent; -import nautilus.game.arcade.events.PlayerPrepareTeleportEvent; -import nautilus.game.arcade.events.PlayerStateChangeEvent; -import nautilus.game.arcade.game.GameTeam.PlayerState; -import nautilus.game.arcade.game.modules.AntiExpOrbModule; -import nautilus.game.arcade.game.modules.Module; -import nautilus.game.arcade.game.modules.gamesummary.GameSummaryModule; -import nautilus.game.arcade.game.team.GameTeamModule; -import nautilus.game.arcade.game.team.selectors.EvenTeamSelector; -import nautilus.game.arcade.game.team.selectors.TeamSelector; -import nautilus.game.arcade.kit.ChampionsKit; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.kit.LinearUpgradeKit; -import nautilus.game.arcade.kit.Perk; -import nautilus.game.arcade.managers.GamePlayerManager; -import nautilus.game.arcade.managers.chat.ChatStatData; -import nautilus.game.arcade.managers.lobby.LobbyManager; -import nautilus.game.arcade.missions.*; -import nautilus.game.arcade.scoreboard.GameScoreboard; -import nautilus.game.arcade.stats.*; -import nautilus.game.arcade.wineffect.WinEffectManager; -import nautilus.game.arcade.world.WorldData; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + import net.minecraft.server.v1_8_R3.EntityItem; import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; + import org.apache.commons.lang3.tuple.Triple; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; @@ -80,9 +48,89 @@ import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import org.bukkit.util.Vector; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; +import com.mojang.authlib.GameProfile; + +import mineplex.core.Managers; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +//import mineplex.core.antihack.AntiHack; +import mineplex.core.arcadeevents.CoreGameStartEvent; +import mineplex.core.arcadeevents.CoreGameStopEvent; +import mineplex.core.command.CommandCenter; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTabTitle; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.elo.EloPlayer; +import mineplex.core.elo.EloTeam; +import mineplex.core.game.MineplexGameManager; +import mineplex.core.game.kit.KitAvailability; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.lifetimes.Lifetimed; +import mineplex.core.lifetimes.ListenerComponent; +import mineplex.core.lifetimes.PhasedLifetime; +import mineplex.core.mission.MissionTracker; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.preferences.Preference; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.utils.UtilGameProfile; +import mineplex.minecraft.game.classcombat.event.ClassCombatCreatureAllowSpawnEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; + +import nautilus.game.arcade.ArcadeFormat; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.events.PlayerGameRespawnEvent; +import nautilus.game.arcade.events.PlayerPrepareTeleportEvent; +import nautilus.game.arcade.events.PlayerStateChangeEvent; +import nautilus.game.arcade.game.GameTeam.PlayerState; +import nautilus.game.arcade.game.modules.AntiExpOrbModule; +import nautilus.game.arcade.game.modules.Module; +import nautilus.game.arcade.game.modules.gamesummary.GameSummaryModule; +import nautilus.game.arcade.game.team.GameTeamModule; +import nautilus.game.arcade.game.team.selectors.EvenTeamSelector; +import nautilus.game.arcade.game.team.selectors.TeamSelector; +import nautilus.game.arcade.kit.ChampionsKit; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.kit.LinearUpgradeKit; +import nautilus.game.arcade.kit.Perk; +import nautilus.game.arcade.managers.GamePlayerManager; +import nautilus.game.arcade.managers.chat.ChatStatData; +import nautilus.game.arcade.managers.lobby.LobbyManager; +import nautilus.game.arcade.missions.BlocksMissionTracker; +import nautilus.game.arcade.missions.CraftItemMissionTracker; +import nautilus.game.arcade.missions.DamageMissionTracker; +import nautilus.game.arcade.missions.EnchantItemMissionTracker; +import nautilus.game.arcade.missions.FurnaceMissionTracker; +import nautilus.game.arcade.missions.GameMissionTracker; +import nautilus.game.arcade.missions.KillMissionTracker; +import nautilus.game.arcade.missions.PlayGameMissionTracker; +import nautilus.game.arcade.missions.WalkMissionTracker; +import nautilus.game.arcade.missions.WinMissionTracker; +import nautilus.game.arcade.scoreboard.GameScoreboard; +import nautilus.game.arcade.stats.AssistsStatTracker; +import nautilus.game.arcade.stats.DamageDealtStatTracker; +import nautilus.game.arcade.stats.DamageTakenStatTracker; +import nautilus.game.arcade.stats.DeathsStatTracker; +import nautilus.game.arcade.stats.ExperienceStatTracker; +import nautilus.game.arcade.stats.GamesPlayedStatTracker; +import nautilus.game.arcade.stats.KillsStatTracker; +import nautilus.game.arcade.stats.LoseStatTracker; +import nautilus.game.arcade.stats.StatTracker; +import nautilus.game.arcade.stats.WinStatTracker; +import nautilus.game.arcade.wineffect.WinEffectManager; +import nautilus.game.arcade.world.WorldData; public abstract class Game extends ListenerComponent implements Lifetimed { @@ -702,6 +750,20 @@ public abstract class Game extends ListenerComponent implements Lifetimed _gameState = state; _gameStateTime = System.currentTimeMillis(); + if (_gameState == Game.GameState.Prepare) + { + // Speed Builders, Master Builders, Draw My Thing, Castle Siege + if (!AnticheatDisabled) + { + //Managers.get(AntiHack.class).enableAnticheat(); + } + } + else if (_gameState == Game.GameState.End && !this.AnticheatDisabled) + { + //Managers.get(AntiHack.class).disableAnticheat(); + } + + if (_gameState == GameState.Live) setGameLiveTime(_gameStateTime); @@ -1362,15 +1424,11 @@ public abstract class Game extends ListenerComponent implements Lifetimed // most gems, since it's been previously sorted as such Player player = teamList.remove(0); - /* - WinEffectManager.prePlay(this, player, teamList, otherList); Location loc = GetSpectatorLocation().clone().add(1000, 0, 1000); loc.setY(200); WinEffectManager.playWinEffect(loc); - - */ } String winnerText = ChatColor.WHITE + "Nobody"; @@ -1442,15 +1500,11 @@ public abstract class Game extends ListenerComponent implements Lifetimed Player player = places.get(0); nonTeamList.remove(player); - /* - WinEffectManager.prePlay(this, player, teamList, nonTeamList); Location loc = GetSpectatorLocation().clone().add(1000, 0, 1000); loc.setY(200); WinEffectManager.playWinEffect(loc); - - */ } for (Player player : UtilServer.getPlayers()) @@ -2071,6 +2125,10 @@ public abstract class Game extends ListenerComponent implements Lifetimed { cleanupModules(); cleanupCommands(); + /* + Managers.get(AntiHack.class).resetIgnoredChecks(); + Managers.get(AntiHack.class).setStrict(false); + */ getLifetime().end(); getStatTrackers().forEach(HandlerList::unregisterAll); getArcadeManager().getMissionsManager().clearTrackers(tracker -> tracker instanceof GameMissionTracker); diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameServerConfig.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameServerConfig.java index d5ec55e3..d3b12c36 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameServerConfig.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameServerConfig.java @@ -1,8 +1,9 @@ package nautilus.game.arcade.game; -import nautilus.game.arcade.GameType; - import java.util.ArrayList; +import java.util.HashMap ; + +import nautilus.game.arcade.GameType; public class GameServerConfig { @@ -53,8 +54,4 @@ public class GameServerConfig { return ServerType != null && MinPlayers != -1 && MaxPlayers != -1; } - - public GameServerConfig(){ - GameList.add(GameType.BaconBrawl); - } } diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bossbattles/BossBattles.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bossbattles/BossBattles.java index fa089c6d..9c12bd47 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bossbattles/BossBattles.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bossbattles/BossBattles.java @@ -41,7 +41,7 @@ public class BossBattles extends TeamGame private ArrayList _displays = new ArrayList(); public BossBattles(ArcadeManager manager) - { + { super(manager, GameType.BossBattles, new Kit[] { new KitBrute(manager), new KitRanger(manager), diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castlesiegenew/CastleSiegeNew.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castlesiegenew/CastleSiegeNew.java index 8ed07f71..605557dc 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castlesiegenew/CastleSiegeNew.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/castlesiegenew/CastleSiegeNew.java @@ -1,28 +1,13 @@ package nautilus.game.arcade.game.games.castlesiegenew; -import mineplex.core.common.util.*; -import mineplex.core.common.util.UtilParticle.ParticleType; -import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.condition.ConditionFactory; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.FirstBloodEvent; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.events.PlayerGameRespawnEvent; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.TeamGame; -import nautilus.game.arcade.game.games.castlesiegenew.kits.*; -import nautilus.game.arcade.game.modules.SpawnShieldModule; -import nautilus.game.arcade.game.modules.compass.CompassModule; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.kit.NullKit; -import nautilus.game.arcade.stats.BloodThirstyStatTracker; -import nautilus.game.arcade.stats.TeamDeathsStatTracker; -import nautilus.game.arcade.stats.TeamKillsStatTracker; -import nautilus.game.arcade.stats.WinAsTeamStatTracker; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; @@ -41,12 +26,47 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; - //import com.mineplex.anticheat.checks.combat.KillauraTypeD; + +import mineplex.core.Managers; //import mineplex.core.antihack.AntiHack; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.condition.ConditionFactory; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.FirstBloodEvent; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.events.PlayerGameRespawnEvent; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.TeamGame; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitHumanKnight; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitHumanMarksman; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitHumanPaladin; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitHumanWolf; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitUndeadArcher; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitUndeadGhoul; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitUndeadSummoner; +import nautilus.game.arcade.game.games.castlesiegenew.kits.KitUndeadZombie; +import nautilus.game.arcade.game.modules.SpawnShieldModule; +import nautilus.game.arcade.game.modules.compass.CompassModule; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.kit.NullKit; +import nautilus.game.arcade.stats.BloodThirstyStatTracker; +import nautilus.game.arcade.stats.TeamDeathsStatTracker; +import nautilus.game.arcade.stats.TeamKillsStatTracker; +import nautilus.game.arcade.stats.WinAsTeamStatTracker; public class CastleSiegeNew extends TeamGame { @@ -150,11 +170,8 @@ public class CastleSiegeNew extends TeamGame .register(this); // Disable specific GWEN checks for this game - /* - AntiHack antiHack = Managers.get(AntiHack.class); - antiHack.addIgnoredCheck(KillauraTypeD.class); - - */ + //AntiHack antiHack = Managers.get(AntiHack.class); + //antiHack.addIgnoredCheck(KillauraTypeD.class); } @Override diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/dragons/Dragons.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/dragons/Dragons.java index f9d28def..f9ec6e8c 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/dragons/Dragons.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/dragons/Dragons.java @@ -1,5 +1,29 @@ package nautilus.game.arcade.game.games.dragons; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.bukkit.EntityEffect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.ItemSpawnEvent; + +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; + +import mineplex.core.Managers; +//import mineplex.core.antihack.AntiHack; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilEnt; @@ -8,6 +32,7 @@ import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.events.PlayerDeathOutEvent; @@ -21,28 +46,6 @@ import nautilus.game.arcade.kit.Perk; import nautilus.game.arcade.kit.perks.PerkSparkler; import nautilus.game.arcade.managers.chat.ChatStatData; import nautilus.game.arcade.stats.SparklezStatTracker; -import org.bukkit.*; -import org.bukkit.entity.EnderDragon; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.EntityTargetEvent; -import org.bukkit.event.entity.ItemSpawnEvent; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; - - - */ -//import mineplex.core.antihack.AntiHack; public class Dragons extends SoloGame { @@ -101,8 +104,7 @@ public class Dragons extends SoloGame antiHack.addIgnoredCheck(Speed.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - - */ + */ } @Override diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/Halloween.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/Halloween.java index 7f049cda..628ef559 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/Halloween.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/Halloween.java @@ -1,6 +1,43 @@ package nautilus.game.arcade.game.games.halloween; -import mineplex.core.common.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import net.minecraft.server.v1_8_R3.Packet; +//import net.minecraft.server.v1_8_R3.PacketPlayOutCustomSoundEffect; +import net.minecraft.server.v1_8_R3.PacketPlayOutNamedSoundEffect; + +import org.bukkit.ChatColor; +import org.bukkit.Difficulty; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +//import com.mineplex.ProtocolVersion; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.gadget.gadgets.mount.types.MountPumpkin; import mineplex.core.recharge.Recharge; @@ -11,6 +48,7 @@ import mineplex.core.treasure.reward.RewardRarity; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.events.GameStateChangeEvent; @@ -21,24 +59,17 @@ import nautilus.game.arcade.game.games.halloween.creatures.InterfaceMove; import nautilus.game.arcade.game.games.halloween.kits.KitFinn; import nautilus.game.arcade.game.games.halloween.kits.KitRobinHood; import nautilus.game.arcade.game.games.halloween.kits.KitThor; -import nautilus.game.arcade.game.games.halloween.waves.*; +import nautilus.game.arcade.game.games.halloween.waves.Wave1; +import nautilus.game.arcade.game.games.halloween.waves.Wave2; +import nautilus.game.arcade.game.games.halloween.waves.Wave3; +import nautilus.game.arcade.game.games.halloween.waves.Wave4; +import nautilus.game.arcade.game.games.halloween.waves.Wave5; +import nautilus.game.arcade.game.games.halloween.waves.WaveBase; +import nautilus.game.arcade.game.games.halloween.waves.WaveBoss; +import nautilus.game.arcade.game.games.halloween.waves.WaveVictory; import nautilus.game.arcade.game.modules.compass.CompassModule; import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.managers.chat.ChatStatData; -import net.minecraft.server.v1_8_R3.Packet; -import net.minecraft.server.v1_8_R3.PacketPlayOutNamedSoundEffect; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.Fireball; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.*; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; - -import java.util.*; public class Halloween extends SoloGame { @@ -648,25 +679,26 @@ public class Halloween extends SoloGame if (!_soundOff.contains(player)) { Packet packet; - int protocol = ((CraftPlayer) player).getHandle().playerConnection.networkManager.getVersion(); + packet = new PacketPlayOutNamedSoundEffect(audio.getAudioPath(), + player.getLocation().getBlockX(), player.getLocation().getBlockY(), + player.getLocation().getBlockZ(), + 20f, 1f); + //TODO: Multi-protocol support /* + int protocol = ((CraftPlayer) player).getHandle().getProtocol(); if (protocol >= ProtocolVersion.v1_12) { packet = new PacketPlayOutCustomSoundEffect(audio.getAudioPath(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), 20f, 1f); - } else { + } else + { packet = new PacketPlayOutNamedSoundEffect(audio.getAudioPath(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(), 20f, 1f); } - - */ - packet = new PacketPlayOutNamedSoundEffect(audio.getAudioPath(), - player.getLocation().getBlockX(), player.getLocation().getBlockY(), - player.getLocation().getBlockZ(), - 20f, 1f); + */ UtilPlayer.sendPacket(player, packet); } diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/hideseek/HideSeek.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/hideseek/HideSeek.java index 54ff0b89..e7b8c92f 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/hideseek/HideSeek.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/hideseek/HideSeek.java @@ -1,11 +1,90 @@ package nautilus.game.arcade.game.games.hideseek; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import net.minecraft.server.v1_8_R3.EntityCreature; +import net.minecraft.server.v1_8_R3.NavigationAbstract; +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Creature; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.FallingSand; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Pig; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Slime; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.util.Vector; + +//import com.mineplex.anticheat.checks.combat.KillauraTypeA; + import mineplex.core.Managers; +//import mineplex.core.antihack.AntiHack; import mineplex.core.common.MinecraftVersion; -import mineplex.core.common.util.*; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; import mineplex.core.disguise.disguises.DisguiseBase; import mineplex.core.disguise.disguises.DisguiseLiving; import mineplex.core.itemstack.ItemStackFactory; @@ -18,6 +97,7 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.core.visibility.VisibilityManager; import mineplex.minecraft.game.core.combat.DeathMessageType; import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.events.GamePrepareCountdownCommence; @@ -29,7 +109,13 @@ import nautilus.game.arcade.game.games.hideseek.forms.BlockForm; import nautilus.game.arcade.game.games.hideseek.forms.CreatureForm; import nautilus.game.arcade.game.games.hideseek.forms.Form; import nautilus.game.arcade.game.games.hideseek.forms.InfestedData; -import nautilus.game.arcade.game.games.hideseek.kits.*; +import nautilus.game.arcade.game.games.hideseek.kits.KitHiderInfestor; +import nautilus.game.arcade.game.games.hideseek.kits.KitHiderQuick; +import nautilus.game.arcade.game.games.hideseek.kits.KitHiderShocker; +import nautilus.game.arcade.game.games.hideseek.kits.KitHiderSwapper; +import nautilus.game.arcade.game.games.hideseek.kits.KitSeekerLeaper; +import nautilus.game.arcade.game.games.hideseek.kits.KitSeekerRadar; +import nautilus.game.arcade.game.games.hideseek.kits.KitSeekerTNT; import nautilus.game.arcade.game.modules.compass.CompassModule; import nautilus.game.arcade.game.modules.rejoin.PlayerRejoinGameEvent; import nautilus.game.arcade.game.modules.rejoin.RejoinModule; @@ -40,36 +126,6 @@ import nautilus.game.arcade.stats.BadHiderStatTracker; import nautilus.game.arcade.stats.HunterKillerStatTracker; import nautilus.game.arcade.stats.HunterOfTheYearStatTracker; import nautilus.game.arcade.stats.MeowStatTracker; -import net.minecraft.server.v1_8_R3.*; -import org.bukkit.*; -import org.bukkit.Material; -import org.bukkit.FireworkEffect.Type; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockDamageEvent; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.bukkit.event.entity.*; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.player.PlayerEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.FireworkMeta; -import org.bukkit.util.Vector; - -import java.util.*; -import java.util.Map.Entry; - -//import com.mineplex.anticheat.checks.combat.KillauraTypeA; -//import mineplex.core.antihack.AntiHack; @SuppressWarnings("deprecation") public class HideSeek extends TeamGame @@ -314,11 +370,11 @@ public class HideSeek extends TeamGame .register(this); StrictAntiHack = true; + /* AntiHack antiHack = Managers.get(AntiHack.class); antiHack.addIgnoredCheck(KillauraTypeA.class); - - */ + */ } @EventHandler diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java index ea8e1fa3..1ff884f8 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java @@ -1,7 +1,55 @@ package nautilus.game.arcade.game.games.minestrike; -import mineplex.core.common.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.NameTagVisibility; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Team; +import org.bukkit.util.Vector; + +//import com.mineplex.anticheat.checks.combat.KillauraTypeA; + +import mineplex.core.Managers; +//import mineplex.core.antihack.AntiHack; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +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.gadget.gadgets.gamemodifiers.GameCosmeticManager; import mineplex.core.gadget.gadgets.gamemodifiers.minestrike.GameModifierMineStrikeSkin; import mineplex.core.gadget.types.Gadget; @@ -29,31 +77,15 @@ import nautilus.game.arcade.game.games.minestrike.kits.KitPlayer; import nautilus.game.arcade.game.modules.compass.CompassModule; import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.managers.chat.ChatStatData; -import nautilus.game.arcade.stats.*; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.*; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.LeatherArmorMeta; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.NameTagVisibility; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Team; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; - -//import com.mineplex.anticheat.checks.combat.KillauraTypeA; -//import mineplex.core.antihack.AntiHack; +import nautilus.game.arcade.stats.KaboomStatTracker; +import nautilus.game.arcade.stats.KillAllOpposingMineStrikeRoundStatTracker; +import nautilus.game.arcade.stats.KillFastStatTracker; +import nautilus.game.arcade.stats.KillReasonStatTracker; +import nautilus.game.arcade.stats.KillsWithConditionStatTracker; +import nautilus.game.arcade.stats.MineStrikeGunStats; +import nautilus.game.arcade.stats.MineStrikeLastAliveKillStatTracker; +import nautilus.game.arcade.stats.TeamDeathsStatTracker; +import nautilus.game.arcade.stats.TeamKillsStatTracker; /** * Minestrike @@ -128,12 +160,9 @@ public class Minestrike extends TeamGame this.AllowParticles = false; this.PlayerGameMode = GameMode.ADVENTURE; - - /* - AntiHack antiHack = Managers.get(AntiHack.class); - antiHack.addIgnoredCheck(KillauraTypeA.class); - - */ + + //AntiHack antiHack = Managers.get(AntiHack.class); + //antiHack.addIgnoredCheck(KillauraTypeA.class); _scoreObj = Scoreboard.getScoreboard().registerNewObjective("HP", "dummy"); _scoreObj.setDisplaySlot(DisplaySlot.BELOW_NAME); diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java index 7acc8bd8..c2c1f50b 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java @@ -1,10 +1,74 @@ package nautilus.game.arcade.game.games.mineware; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + import com.google.common.collect.Lists; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; + +import mineplex.core.Managers; +//import mineplex.core.antihack.AntiHack; import mineplex.core.common.Pair; -import mineplex.core.common.util.*; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTextTop; +import mineplex.core.common.util.UtilTime; import mineplex.core.incognito.IncognitoManager; import mineplex.core.projectile.IThrown; import mineplex.core.projectile.ProjectileUser; @@ -24,44 +88,50 @@ import nautilus.game.arcade.game.games.mineware.challenge.Challenge; import nautilus.game.arcade.game.games.mineware.challenge.ChallengeData; import nautilus.game.arcade.game.games.mineware.challenge.ChallengeList; import nautilus.game.arcade.game.games.mineware.challenge.ChallengeSettings; -import nautilus.game.arcade.game.games.mineware.challenge.type.*; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeAnvilDance; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeArrowRampage; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeBlockLobbers; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeBouncingBlock; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeBuildRace; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeChickenShooting; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeColorChange; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeDeadlyTnt; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeDiamondHunt; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeEggSmash; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeFallingBlocks; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeFastFood; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeKangarooJump; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeKingOfTheLadder; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeLavaRun; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeMilkACow; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeMinecartDance; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeMiniOneInTheQuiver; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeOreRun; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengePickASide; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengePunchThePig; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeRedLightGreenLight; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeReverseTag; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeRushPush; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeSmashOff; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeTreasureDigger; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeWaterHorror; +import nautilus.game.arcade.game.games.mineware.challenge.type.ChallengeWaveCrush; import nautilus.game.arcade.game.games.mineware.effect.ChickenAttack; import nautilus.game.arcade.game.games.mineware.effect.DeathEffect; import nautilus.game.arcade.game.games.mineware.effect.DeathEffectData; import nautilus.game.arcade.game.games.mineware.events.ChallengeEndEvent; import nautilus.game.arcade.game.games.mineware.kit.KitBawksFood; -import nautilus.game.arcade.game.games.mineware.tracker.*; +import nautilus.game.arcade.game.games.mineware.tracker.BouncingShadowTracker; +import nautilus.game.arcade.game.games.mineware.tracker.DragonKingTracker; +import nautilus.game.arcade.game.games.mineware.tracker.EliteArcherTracker; +import nautilus.game.arcade.game.games.mineware.tracker.MilkManTracker; +import nautilus.game.arcade.game.games.mineware.tracker.PinataMasterTracker; +import nautilus.game.arcade.game.games.mineware.tracker.PixelNinjaTracker; +import nautilus.game.arcade.game.games.mineware.tracker.SpeedyBuildersTracker; +import nautilus.game.arcade.game.games.mineware.tracker.SurfUpTracker; +import nautilus.game.arcade.game.games.mineware.tracker.TagMasterTracker; +import nautilus.game.arcade.game.games.mineware.tracker.VeteranTracker; import nautilus.game.arcade.kit.Kit; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.ItemSpawnEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.player.*; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.*; - -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; - - - */ -//import mineplex.core.antihack.AntiHack; /** *

@@ -187,18 +257,25 @@ public class BawkBawkBattles extends TeamGame implements IThrown FixSpawnFacing = false; Manager.GetCreature().SetDisableCustomDrops(true); - /* AntiHack antiHack = Managers.get(AntiHack.class); antiHack.addIgnoredCheck(Speed.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - - */ - + */ populateChallenges(); - registerStatTrackers(new BouncingShadowTracker(this), new DragonKingTracker(this), new EliteArcherTracker(this), new MilkManTracker(this), new PinataMasterTracker(this), new PixelNinjaTracker(this), new SpeedyBuildersTracker(this), new SurfUpTracker(this), new TagMasterTracker(this), new VeteranTracker(this)); + registerStatTrackers( + new BouncingShadowTracker(this), + new DragonKingTracker(this), + new EliteArcherTracker(this), + new MilkManTracker(this), + new PinataMasterTracker(this), + new PixelNinjaTracker(this), + new SpeedyBuildersTracker(this), + new SurfUpTracker(this), + new TagMasterTracker(this), + new VeteranTracker(this)); } public void populateChallenges() diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/challenge/Challenge.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/challenge/Challenge.java index 3809d529..599d3b8f 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/challenge/Challenge.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/challenge/Challenge.java @@ -1,23 +1,21 @@ package nautilus.game.arcade.game.games.mineware.challenge; -import mineplex.core.common.util.*; -import mineplex.core.common.util.UtilParticle.ParticleType; -import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.hologram.Hologram; -import mineplex.core.hologram.Hologram.HologramTarget; -import mineplex.core.projectile.ProjectileUser; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.condition.Condition.ConditionType; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.games.mineware.BawkBawkBattles; -import nautilus.game.arcade.game.games.mineware.events.ChallengeEndEvent; -import nautilus.game.arcade.game.games.mineware.events.ChallengeStartEvent; -import nautilus.game.arcade.world.WorldData; -import net.minecraft.server.v1_8_R3.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.Blocks; +import net.minecraft.server.v1_8_R3.ChunkSection; +import net.minecraft.server.v1_8_R3.IBlockData; +import net.minecraft.server.v1_8_R3.WorldServer; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.World; -import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; @@ -37,9 +35,32 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.hologram.Hologram; +import mineplex.core.hologram.Hologram.HologramTarget; +import mineplex.core.projectile.ProjectileUser; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.condition.Condition.ConditionType; + +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.mineware.BawkBawkBattles; +import nautilus.game.arcade.game.games.mineware.events.ChallengeEndEvent; +import nautilus.game.arcade.game.games.mineware.events.ChallengeStartEvent; +import nautilus.game.arcade.world.WorldData; /** *

@@ -575,6 +596,8 @@ public abstract class Challenge implements Listener { if (block != Blocks.AIR) { + //chunksection = chunk.getSections()[y >> 4] = new ChunkSection(y >> 4 << 4, chunk, !nmsWorld.worldProvider.o()); + //??? chunksection = chunk.getSections()[y >> 4] = new ChunkSection(y >> 4 << 4, !nmsWorld.worldProvider.o()); } } diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/Moba.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/Moba.java index 59533502..a182ab8d 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/Moba.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/Moba.java @@ -1,7 +1,34 @@ package nautilus.game.arcade.game.games.moba; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +//import com.mineplex.anticheat.checks.combat.KillauraTypeD; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; + import mineplex.core.Managers; import mineplex.core.account.permissions.Permission; +//import mineplex.core.account.permissions.PermissionGroup; +//import mineplex.core.antihack.AntiHack; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilServer; @@ -15,6 +42,7 @@ import mineplex.core.leaderboard.LeaderboardManager; import mineplex.core.leaderboard.LeaderboardRepository.LeaderboardSQLType; import mineplex.core.leaderboard.StaticLeaderboard; import mineplex.minecraft.game.core.combat.DeathMessageType; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.events.GameStateChangeEvent; @@ -54,28 +82,6 @@ import nautilus.game.arcade.game.modules.capturepoint.CapturePointModule; import nautilus.game.arcade.game.modules.compass.CompassModule; import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.managers.lobby.current.NewGameLobbyManager; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.entity.Arrow; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.ProjectileHitEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.*; - -/* -import com.mineplex.anticheat.checks.combat.KillauraTypeD; -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; - - - */ -//import mineplex.core.antihack.AntiHack; public class Moba extends TeamGame { @@ -178,8 +184,7 @@ public class Moba extends TeamGame antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); antiHack.addIgnoredCheck(KillauraTypeD.class); - - */ + */ } protected T registerManager(T listener) diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/runner/Runner.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/runner/Runner.java index c9fd16b8..05f6c295 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/runner/Runner.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/runner/Runner.java @@ -1,11 +1,41 @@ package nautilus.game.arcade.game.games.runner; +import java.util.HashMap; +import java.util.Map; + +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.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.ProjectileHitEvent; + +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; + +import mineplex.core.Managers; +//import mineplex.core.antihack.AntiHack; import mineplex.core.common.Pair; -import mineplex.core.common.util.*; +import mineplex.core.common.util.C; +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; import mineplex.core.projectile.IThrown; import mineplex.core.projectile.ProjectileUser; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.game.SoloGame; @@ -16,27 +46,6 @@ import nautilus.game.arcade.game.modules.compass.CompassModule; import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.managers.chat.ChatStatData; import nautilus.game.arcade.stats.DistanceTraveledStatTracker; -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.entity.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityChangeBlockEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.ProjectileHitEvent; - -import java.util.HashMap; -import java.util.Map; - -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; - - */ -//import mineplex.core.antihack.AntiHack; public class Runner extends SoloGame implements IThrown { @@ -82,13 +91,12 @@ public class Runner extends SoloGame implements IThrown ); /* - AntiHack antiHack = Managers.get(AntiHack.class); antiHack.addIgnoredCheck(Speed.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - */ + */ } @EventHandler diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/BoosterRing.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/BoosterRing.java index c73449e2..b328e5ea 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/BoosterRing.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/BoosterRing.java @@ -16,7 +16,6 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; -import org.omg.DynamicAny._DynUnionStub; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilBlock; diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Crumbleable.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Crumbleable.java index 6aab2515..a2c1e1cd 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Crumbleable.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Crumbleable.java @@ -1,8 +1,14 @@ package nautilus.game.arcade.game.games.skyfall; -import mineplex.core.common.util.*; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + import net.minecraft.server.v1_8_R3.Chunk; import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk; + import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; @@ -11,10 +17,11 @@ import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_8_R3.CraftChunk; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.HashMap; -import java.util.Map; +import mineplex.core.common.util.MapUtil; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; /** * Crumbleable is a Superclass to create decayable/crumleable Objects like Sky Islands @@ -147,6 +154,7 @@ public abstract class Crumbleable for (Player player : UtilServer.getPlayers()) { int protocol = UtilPlayer.getProtocol(player); + //UtilPlayer.sendPacket(player, new PacketPlayOutMapChunk(protocol, chunk, false, mask)); UtilPlayer.sendPacket(player, new PacketPlayOutMapChunk(chunk, false, mask)); } diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Skyfall.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Skyfall.java index fdab83e0..64d46279 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Skyfall.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skyfall/Skyfall.java @@ -1,33 +1,20 @@ package nautilus.game.arcade.game.games.skyfall; -import mineplex.core.common.MinecraftVersion; -import mineplex.core.common.util.*; -import mineplex.core.common.util.UtilEvent.ActionType; -import mineplex.core.common.util.UtilParticle.ParticleType; -import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.loot.ChestLoot; -import mineplex.core.recharge.Recharge; -import mineplex.core.titles.tracks.standard.LuckyTrack; -import mineplex.core.titles.tracks.standard.UnluckyTrack; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.ChestRefillEvent; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.games.skyfall.kits.*; -import nautilus.game.arcade.game.games.skyfall.stats.AeronaughtStatTracker; -import nautilus.game.arcade.game.games.skyfall.stats.RingStatTracker; -import nautilus.game.arcade.game.modules.VersionModule; -import nautilus.game.arcade.game.modules.compass.CompassModule; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.stats.KillsWithinTimeLimitStatTracker; -import nautilus.game.arcade.stats.WinWithoutWearingArmorStatTracker; -import net.md_5.bungee.api.ChatColor; -import org.bukkit.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.TreeMap; +import java.util.UUID; + +import org.bukkit.Color; +import org.bukkit.Effect; +import org.bukkit.FireworkEffect; import org.bukkit.FireworkEffect.Type; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Chest; @@ -53,16 +40,55 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import java.util.*; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; - - - */ +import mineplex.core.Managers; //import mineplex.core.antihack.AntiHack; +import mineplex.core.common.MinecraftVersion; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.loot.ChestLoot; +import mineplex.core.recharge.Recharge; +import mineplex.core.titles.tracks.standard.LuckyTrack; +import mineplex.core.titles.tracks.standard.UnluckyTrack; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.ChestRefillEvent; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.game.Game; +import nautilus.game.arcade.game.games.skyfall.kits.KitAeronaught; +import nautilus.game.arcade.game.games.skyfall.kits.KitBooster; +import nautilus.game.arcade.game.games.skyfall.kits.KitDeadeye; +import nautilus.game.arcade.game.games.skyfall.kits.KitJouster; +import nautilus.game.arcade.game.games.skyfall.kits.KitSpeeder; +import nautilus.game.arcade.game.games.skyfall.kits.KitStunner; +import nautilus.game.arcade.game.games.skyfall.stats.AeronaughtStatTracker; +import nautilus.game.arcade.game.games.skyfall.stats.RingStatTracker; +import nautilus.game.arcade.game.modules.VersionModule; +import nautilus.game.arcade.game.modules.compass.CompassModule; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.stats.KillsWithinTimeLimitStatTracker; +import nautilus.game.arcade.stats.WinWithoutWearingArmorStatTracker; +import net.md_5.bungee.api.ChatColor; /** * GameObject of the game Skyfall @@ -180,9 +206,7 @@ public abstract class Skyfall extends Game antiHack.addIgnoredCheck(Speed.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - - */ - + */ _islands = new HashMap<>(); _boosterRings = new ArrayList<>(); _tntMap = new HashMap<>(); diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmash.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmash.java index f9a104bd..d6abfa4c 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmash.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmash.java @@ -1,10 +1,56 @@ package nautilus.game.arcade.game.games.smash; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + import com.google.common.collect.Sets; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.Speed; + +import mineplex.core.Managers; import mineplex.core.account.permissions.Permission; import mineplex.core.account.permissions.PermissionGroup; +//import mineplex.core.antihack.AntiHack; import mineplex.core.blockrestore.BlockRestore; -import mineplex.core.common.util.*; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +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.gadget.types.Gadget; import mineplex.core.gadget.types.GadgetType; import mineplex.core.hologram.Hologram; @@ -22,41 +68,33 @@ import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.GameTeam; import nautilus.game.arcade.game.GameTeam.PlayerState; import nautilus.game.arcade.game.games.smash.events.SmashActivateEvent; -import nautilus.game.arcade.game.games.smash.kits.*; +import nautilus.game.arcade.game.games.smash.kits.KitBlaze; +import nautilus.game.arcade.game.games.smash.kits.KitChicken; +import nautilus.game.arcade.game.games.smash.kits.KitCow; +import nautilus.game.arcade.game.games.smash.kits.KitCreeper; +import nautilus.game.arcade.game.games.smash.kits.KitEnderman; +import nautilus.game.arcade.game.games.smash.kits.KitGolem; +import nautilus.game.arcade.game.games.smash.kits.KitGuardian; +import nautilus.game.arcade.game.games.smash.kits.KitMagmaCube; +import nautilus.game.arcade.game.games.smash.kits.KitPig; +import nautilus.game.arcade.game.games.smash.kits.KitSheep; +import nautilus.game.arcade.game.games.smash.kits.KitSkeletalHorse; +import nautilus.game.arcade.game.games.smash.kits.KitSkeleton; +import nautilus.game.arcade.game.games.smash.kits.KitSkySquid; +import nautilus.game.arcade.game.games.smash.kits.KitSlime; +import nautilus.game.arcade.game.games.smash.kits.KitSnowman; +import nautilus.game.arcade.game.games.smash.kits.KitSpider; +import nautilus.game.arcade.game.games.smash.kits.KitVillager; +import nautilus.game.arcade.game.games.smash.kits.KitWitch; +import nautilus.game.arcade.game.games.smash.kits.KitWitherSkeleton; +import nautilus.game.arcade.game.games.smash.kits.KitWolf; +import nautilus.game.arcade.game.games.smash.kits.KitZombie; import nautilus.game.arcade.game.games.smash.mission.AirborneTracker; import nautilus.game.arcade.game.games.smash.perks.SmashUltimate; import nautilus.game.arcade.game.modules.compass.CompassModule; import nautilus.game.arcade.game.modules.perks.PerkSpreadsheetModule; import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.kit.Perk; -import org.bukkit.*; -import org.bukkit.FireworkEffect.Type; -import org.bukkit.block.Block; -import org.bukkit.entity.EnderCrystal; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.BlockFadeEvent; -import org.bukkit.event.entity.*; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.Speed; - - */ -//import mineplex.core.antihack.AntiHack; public abstract class SuperSmash extends Game { @@ -118,8 +156,7 @@ public abstract class SuperSmash extends Game AntiHack antiHack = Managers.get(AntiHack.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(Speed.class); - - */ + */ manager.GetExplosion().SetRegenerate(true); manager.GetExplosion().setRegenerateTime(TimeUnit.SECONDS.toMillis(30)); diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmashDominate.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmashDominate.java index b2ee8f7e..5a315aaa 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmashDominate.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/SuperSmashDominate.java @@ -1,17 +1,5 @@ package nautilus.game.arcade.game.games.smash; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilInv; -import mineplex.core.common.util.UtilPlayer; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.ArcadeFormat; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.games.common.Domination; -import nautilus.game.arcade.game.games.smash.kits.*; -import nautilus.game.arcade.kit.Kit; -import nautilus.game.arcade.managers.chat.ChatStatData; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -24,13 +12,39 @@ import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.player.PlayerInteractEvent; -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; - */ +import mineplex.core.Managers; //import mineplex.core.antihack.AntiHack; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import nautilus.game.arcade.ArcadeFormat; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.common.Domination; +import nautilus.game.arcade.game.games.smash.kits.KitBlaze; +import nautilus.game.arcade.game.games.smash.kits.KitChicken; +import nautilus.game.arcade.game.games.smash.kits.KitCreeper; +import nautilus.game.arcade.game.games.smash.kits.KitEnderman; +import nautilus.game.arcade.game.games.smash.kits.KitGolem; +import nautilus.game.arcade.game.games.smash.kits.KitMagmaCube; +import nautilus.game.arcade.game.games.smash.kits.KitPig; +import nautilus.game.arcade.game.games.smash.kits.KitSkeletalHorse; +import nautilus.game.arcade.game.games.smash.kits.KitSkeleton; +import nautilus.game.arcade.game.games.smash.kits.KitSkySquid; +import nautilus.game.arcade.game.games.smash.kits.KitSlime; +import nautilus.game.arcade.game.games.smash.kits.KitSnowman; +import nautilus.game.arcade.game.games.smash.kits.KitSpider; +import nautilus.game.arcade.game.games.smash.kits.KitWitch; +import nautilus.game.arcade.game.games.smash.kits.KitWitherSkeleton; +import nautilus.game.arcade.game.games.smash.kits.KitWolf; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.managers.chat.ChatStatData; public class SuperSmashDominate extends Domination { @@ -76,13 +90,12 @@ public class SuperSmashDominate extends Domination ); /* - AntiHack antiHack = Managers.get(AntiHack.class); antiHack.addIgnoredCheck(Speed.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - */ + */ } @EventHandler(priority = EventPriority.LOWEST) diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/squidshooters/SquidShooters.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/squidshooters/SquidShooters.java index f613d6a1..ba339943 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/squidshooters/SquidShooters.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/squidshooters/SquidShooters.java @@ -1,20 +1,13 @@ package nautilus.game.arcade.game.games.squidshooters; -import mineplex.core.common.Pair; -import mineplex.core.common.util.*; -import mineplex.core.disguise.disguises.DisguiseSquid; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.combat.CombatComponent; -import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.events.PlayerPrepareTeleportEvent; -import nautilus.game.arcade.game.SoloGame; -import nautilus.game.arcade.game.games.squidshooters.kit.KitRetroSquid; -import nautilus.game.arcade.kit.Kit; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -27,16 +20,34 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import java.util.*; -import java.util.stream.Collectors; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; +//import com.mineplex.anticheat.checks.move.Speed; -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; -import com.mineplex.anticheat.checks.move.Speed; - - */ +import mineplex.core.Managers; //import mineplex.core.antihack.AntiHack; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.disguise.disguises.DisguiseSquid; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.combat.CombatComponent; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.events.PlayerPrepareTeleportEvent; +import nautilus.game.arcade.game.SoloGame; +import nautilus.game.arcade.game.games.squidshooters.kit.KitRetroSquid; +import nautilus.game.arcade.kit.Kit; public class SquidShooters extends SoloGame { @@ -71,8 +82,7 @@ public class SquidShooters extends SoloGame antiHack.addIgnoredCheck(Speed.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - - */ + */ } @Override diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/tug/TugOfWool.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/tug/TugOfWool.java index 99b0ebae..dea01525 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/tug/TugOfWool.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/tug/TugOfWool.java @@ -1,22 +1,13 @@ package nautilus.game.arcade.game.games.tug; -import mineplex.core.common.util.*; -import mineplex.core.itemstack.ItemBuilder; -import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.GameType; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.events.PlayerKitGiveEvent; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.TeamGame; -import nautilus.game.arcade.game.games.tug.entities.*; -import nautilus.game.arcade.game.games.tug.kits.KitTugArcher; -import nautilus.game.arcade.game.games.tug.kits.KitTugLeaper; -import nautilus.game.arcade.game.games.tug.kits.KitTugSmasher; -import nautilus.game.arcade.kit.Kit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; @@ -37,16 +28,38 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; -import java.util.*; -import java.util.concurrent.TimeUnit; +//import com.mineplex.anticheat.checks.move.Glide; +//import com.mineplex.anticheat.checks.move.HeadRoll; -/* -import com.mineplex.anticheat.checks.move.Glide; -import com.mineplex.anticheat.checks.move.HeadRoll; - - - */ +import mineplex.core.Managers; //import mineplex.core.antihack.AntiHack; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.events.PlayerKitGiveEvent; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.TeamGame; +import nautilus.game.arcade.game.games.tug.entities.TugChicken; +import nautilus.game.arcade.game.games.tug.entities.TugCow; +import nautilus.game.arcade.game.games.tug.entities.TugEntity; +import nautilus.game.arcade.game.games.tug.entities.TugPig; +import nautilus.game.arcade.game.games.tug.entities.TugSheep; +import nautilus.game.arcade.game.games.tug.kits.KitTugArcher; +import nautilus.game.arcade.game.games.tug.kits.KitTugLeaper; +import nautilus.game.arcade.game.games.tug.kits.KitTugSmasher; +import nautilus.game.arcade.kit.Kit; public class TugOfWool extends TeamGame { @@ -95,8 +108,6 @@ public class TugOfWool extends TeamGame AntiHack antiHack = Managers.get(AntiHack.class); antiHack.addIgnoredCheck(Glide.class); antiHack.addIgnoredCheck(HeadRoll.class); - - */ registerChatStats( Kills, Deaths, @@ -104,6 +115,7 @@ public class TugOfWool extends TeamGame DamageDealt, DamageTaken ); + */ } @Override diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/VersionModule.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/VersionModule.java index 27650bec..37ca50f4 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/VersionModule.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/VersionModule.java @@ -1,5 +1,10 @@ package nautilus.game.arcade.game.modules; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; + import mineplex.core.common.MinecraftVersion; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilPlayer; @@ -7,7 +12,6 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.portal.GenericServer; import mineplex.core.portal.Intent; import mineplex.core.portal.Portal; -import org.bukkit.entity.Player; /** * This module functions as a checkpoint for any client connecting a game @@ -32,4 +36,13 @@ public class VersionModule extends Module } } } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event) + { + if (MinecraftVersion.fromInt(event.getUniqueId().version()) != _minecraftVersion) + { + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, C.cGold + C.Bold + "Please use Minecraft " + _minecraftVersion.friendlyName() + " or newer to play this game!"); + } + } } \ No newline at end of file diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameCreationManager.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameCreationManager.java index 99553142..b16e1ec7 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameCreationManager.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameCreationManager.java @@ -1,5 +1,20 @@ package nautilus.game.arcade.managers; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + import mineplex.core.common.Pair; import mineplex.core.common.timing.TimingManager; import mineplex.core.common.util.UtilAlg; @@ -10,6 +25,7 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.combat.CombatManager.AttackReason; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameMode; import nautilus.game.arcade.GameType; @@ -20,14 +36,6 @@ import nautilus.game.arcade.managers.voting.Vote; import nautilus.game.arcade.managers.voting.VotingManager; import nautilus.game.arcade.managers.voting.types.GameVote; import nautilus.game.arcade.managers.voting.types.MapVote; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -import java.lang.reflect.InvocationTargetException; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; public class GameCreationManager implements Listener { @@ -249,6 +257,9 @@ public class GameCreationManager implements Listener Manager.GetDamage().GetCombatManager().setUseWeaponName(AttackReason.CustomWeaponName); ItemStackFactory.Instance.SetUseCustomNames(false); + //Champions + Manager.toggleChampionsModules(gameType); + _lastGames.add(0, gameType); // GameModes diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java index c6d434f5..6922b783 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java @@ -1,27 +1,12 @@ package nautilus.game.arcade.managers; -import mineplex.core.account.permissions.Permission; -import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.common.util.*; -import mineplex.core.itemstack.ItemStackFactory; -import mineplex.core.preferences.Preference; -import mineplex.core.recharge.Recharge; -import mineplex.core.teleport.event.MineplexTeleportEvent; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.minecraft.game.core.condition.Condition.ConditionType; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.ArcadeManager; -import nautilus.game.arcade.events.GameStateChangeEvent; -import nautilus.game.arcade.events.PlayerDeathOutEvent; -import nautilus.game.arcade.game.Game; -import nautilus.game.arcade.game.Game.GameState; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.GameTeam.PlayerState; -import nautilus.game.arcade.kit.perks.event.PerkDestructorBlockEvent; -import nautilus.game.arcade.world.WorldData; import net.minecraft.server.v1_8_R3.EntityPlayer; -import org.bukkit.*; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Chest; @@ -34,8 +19,13 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import org.bukkit.event.block.*; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.LeavesDecayEvent; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; @@ -43,11 +33,52 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryType; -import org.bukkit.event.player.*; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; +import mineplex.core.Managers; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +//import mineplex.core.antihack.AntiHack; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.preferences.Preference; +import mineplex.core.recharge.Recharge; +import mineplex.core.teleport.event.MineplexTeleportEvent; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.condition.Condition.ConditionType; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.events.PlayerDeathOutEvent; +import nautilus.game.arcade.game.Game; +import nautilus.game.arcade.game.Game.GameState; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.GameTeam.PlayerState; +import nautilus.game.arcade.kit.perks.event.PerkDestructorBlockEvent; +import nautilus.game.arcade.world.WorldData; + public class GameFlagManager implements Listener { public enum Perm implements Permission @@ -1280,6 +1311,17 @@ public class GameFlagManager implements Listener } } + /* + @EventHandler + public void AntiHackStrict(GameStateChangeEvent event) + { + if (event.GetState() == GameState.Prepare || event.GetState() == GameState.Live) + Managers.get(AntiHack.class).setStrict(event.GetGame().StrictAntiHack); + else + Managers.get(AntiHack.class).setStrict(true); + } + */ + @EventHandler public void PlayerKillCommandCancel(PlayerCommandPreprocessEvent event) { diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index 672ef62b..4813b010 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -1,34 +1,62 @@ package nautilus.game.arcade.managers; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +//import com.mineplex.anticheat.MineplexAnticheat; +//import com.mineplex.anticheat.checks.move.Glide; + import mineplex.core.Managers; import mineplex.core.account.permissions.Permission; import mineplex.core.account.permissions.PermissionGroup; -import mineplex.core.common.util.*; -import mineplex.core.communities.CommunityManager; +//import mineplex.core.antihack.AntiHack; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilGear; +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.communities.data.Community; -import mineplex.core.communities.data.CommunityRole; import mineplex.core.communities.events.CommunityDisbandEvent; +import mineplex.core.communities.CommunityManager; +import mineplex.core.communities.data.CommunityRole; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.portal.GenericServer; import mineplex.core.portal.Intent; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.events.GameStateChangeEvent; import nautilus.game.arcade.game.Game.GameState; import nautilus.game.arcade.gui.privateServer.PrivateServerShop; import nautilus.game.arcade.gui.privateServer.page.GameVotingPage; -import org.bukkit.*; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.event.player.*; -import org.bukkit.plugin.Plugin; - -import java.util.*; public class GameHostManager implements Listener { @@ -39,6 +67,7 @@ public class GameHostManager implements Listener INCREASE_MAX_PLAYERS_100, } + //private final AntiHack _antiHack; private List _games = new ArrayList<>(); ArcadeManager Manager; @@ -68,6 +97,7 @@ public class GameHostManager implements Listener public GameHostManager(ArcadeManager manager) { + //_antiHack = Managers.require(AntiHack.class); Manager = manager; _shop = new PrivateServerShop(manager, manager.GetClients(), manager.GetDonation()); Manager.getPluginManager().registerEvents(this, Manager.getPlugin()); @@ -91,11 +121,9 @@ public class GameHostManager implements Listener _games.add(GameType.Evolution); _games.add(GameType.MonsterMaze); _games.add(GameType.Gladiators); - /* _games.add(GameType.ChampionsDominate); _games.add(GameType.ChampionsTDM); _games.add(GameType.ChampionsCTF); - */ _games.add(GameType.HideSeek); _games.add(GameType.Draw); _games.add(GameType.Bridge); @@ -162,6 +190,8 @@ public class GameHostManager implements Listener } // Disable all checks in event servers + //Stream.concat(AntiHack.ACTIONS.keySet().stream(), AntiHack.CHECKS.keySet().stream()).distinct().forEach(_antiHack::addIgnoredCheck); + //JavaPlugin.getPlugin(MineplexAnticheat.class).getCheckManager().disableCheck(Glide.class); } @EventHandler diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/legacy/LegacyGameLobbyManager.java b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/legacy/LegacyGameLobbyManager.java index 7ad6d0a0..4d6c3bdb 100644 --- a/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/legacy/LegacyGameLobbyManager.java +++ b/Plugins[Modified]/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/lobby/legacy/LegacyGameLobbyManager.java @@ -1,11 +1,25 @@ package nautilus.game.arcade.managers.lobby.legacy; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Sheep; + import com.google.common.collect.Lists; + import mineplex.core.common.util.MapUtil; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilWorld; import mineplex.core.game.kit.KitAvailability; + import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.GameType; import nautilus.game.arcade.game.Game; @@ -14,17 +28,6 @@ import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.kit.KitSorter; import nautilus.game.arcade.managers.LobbyEnt; import nautilus.game.arcade.managers.lobby.LobbyManager; -import org.bukkit.DyeColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Sheep; - -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; public class LegacyGameLobbyManager extends LobbyManager { @@ -37,28 +40,28 @@ public class LegacyGameLobbyManager extends LobbyManager super( manager, // Missions - new Location(WORLD, -2, 61, 3, -145, 0), + new Location(WORLD, -3.5, 102, 3.5, -145, 0), null, // Spawn - new Location(WORLD, 0, 61, 0), + new Location(WORLD, 0, 104, 0), // Amp Stand - new Location(WORLD, 0, 60, 11) + new Location(WORLD, 0, 102.5, -15) ); - setGameText(new Location(WORLD, 0, 90, 50)); - setKitText(new Location(WORLD, -40, 80, 0)); - setTeamText(new Location(WORLD, 40, 80, 0)); - setAdvText(new Location(WORLD, 0, 100, -60)); + setGameText(new Location(WORLD, 0, 130, 50)); + setKitText(new Location(WORLD, -40, 120, 0)); + setTeamText(new Location(WORLD, 40, 120, 0)); + setAdvText(new Location(WORLD, 0, 140, -60)); - setPodium(new Location(WORLD, 0, 60, -11), Material.EMERALD_BLOCK.getId(), (byte) 0); + setPodium(new Location(WORLD, 0, 101.5, -15), Material.EMERALD_BLOCK.getId(), (byte) 0); - _kitDisplay = new Location(WORLD, -17, 60, 0); + _kitDisplay = new Location(WORLD, -17, 101, 0); float yaw = UtilAlg.GetYaw(UtilAlg.getTrajectory(_kitDisplay, getSpawn())); yaw = Math.round(yaw / 90) * 90; _kitDisplay.setYaw(yaw); - _teamDisplay = new Location(WORLD, 18, 60, 0); + _teamDisplay = new Location(WORLD, 18, 101, 0); yaw = UtilAlg.GetYaw(UtilAlg.getTrajectory(_teamDisplay, getSpawn())); yaw = Math.round(yaw / 90) * 90; diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/target/classes/plugin.yml b/Plugins[Modified]/Nautilus.Game.Arcade/target/classes/plugin.yml new file mode 100644 index 00000000..d4bbeca8 --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade/target/classes/plugin.yml @@ -0,0 +1,4 @@ +name: Arcade +main: nautilus.game.arcade.Arcade +version: 0.1 +loadbefore: [MineplexAnticheat] diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Plugins[Modified]/Nautilus.Game.Arcade/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 00000000..e69de29b diff --git a/Plugins[Modified]/Nautilus.Game.Arcade/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Plugins[Modified]/Nautilus.Game.Arcade/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 00000000..d7393232 --- /dev/null +++ b/Plugins[Modified]/Nautilus.Game.Arcade/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,1538 @@ +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\types\MapVote.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SimultaneousSkeletonStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\perks\PerkPaintballSniper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeletalhorse\PerkHorseKick.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitBerserker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\effect\ChickenAttack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBackstab.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\kits\KitBriber.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkNoFallDamage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\modes\MobaMonochromeMap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameRewardManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\common\LeashedEntity.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\minion\Minion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\hotbar\HotbarEditor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\Wave5.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\UHC.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\turfforts\kits\KitMarksman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitHiderShocker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\Smoke.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitWolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\FireflyData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\page\OptionsPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\CastleSiegeKing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\FlashBang.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\Maze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\basketball\data\ScoringManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\DataLoc.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\ctf_data\CarrierCombatDeathEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\buildmavericks\BuildDataCylinder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\KitCakeFrosting.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TntMinerStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitGolem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitBeastmaster.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitEnderman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\GameSummaryComponentType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\common\SkillSword.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\ai\goal\MobaDirectAIMethod.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\runner\kits\KitLeaper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\MrSquiggleStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\ui\VotingShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameLootManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TheComebackStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\kits\KitDisruptor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\TeamTowerBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\perk\PerkPassiveWoolGain.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaHitConditionEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\Gravity.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\ChallengeSettings.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\hattori\SkillSnowball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\CancelNextGameCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkChampion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\kits\perks\PerkWaller.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeDiamondHunt.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\IceMaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitMiner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\MazeBlockData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitBrawler.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KeenEyeStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\progression\ui\MobaRolePage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\buff\BuffManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameHostManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragons\kits\KitCoward.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\kits\KitHealth.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\TournamentStopCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\MobaRole.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitLeaper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PlayerKitGiveEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\equipment\armor\Helmet.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\spleef\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\ai\goal\MobaAIMethod.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\RemoveAdminButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\TeamRequestsModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaBasicAttackDamageEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\forms\BlockForm.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeChickenShooting.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimateNinja.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SparklezStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\UHCSolo.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\ZombieSurvival.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\kits\perks\PerkRepulsor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\Gladiators.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackThrowTNT.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bob\SkillBuildPainting.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\creeper\PerkCreeperSulphurBomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\FirstStrikeTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\forms\InfestedData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkInfernoFinn.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\ivy\SkillBoxingRing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeDeadlyTnt.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\progression\MobaUnlockAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\trackers\TrackerDirectHit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\BasePage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\WoolBombData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sheep\kits\KitBrute.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\WaveVictory.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\villager\PerkVillagerShot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\ComplexSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\data\DemolitionData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\worldmap\WorldMapRenderer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\devon\SkillBoost.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\FirstBloodStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\spleef\kits\KitBrawler.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\pumpkin\PumpkinBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\Module.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\KitUnlockCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\buff\buffs\BuffPumpkinKing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkSiesmicSlamEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\biff\SkillLeash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeletalhorse\PerkBoneRush.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\kit\KitWitherMinion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\buff\Buff.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSeismicSlamSND.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\ui\CakeResourceShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\medals\MedalType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\PerfectionistStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellHeal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SharpShooterStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\runner\kits\KitFrosty.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSpider.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\parts\Part5.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\SneakyAssassins.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\KitRifle.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\wineffect\WinEffectManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\page\ParticlesPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\witch\SmashWitch.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\progression\MobaProgression.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\ModuleSuperArrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\kit\PerkBlaster.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\kits\KitAbility.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\PerkThorns.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\cow\DataCowMilkSpiral.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\kits\KitSurvivorRogue.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\PowerUpType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\dominate_data\Resupply.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\HalloweenAudio.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeResource.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkApple.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\TugTeam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\event\EventModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\trackers\SnowmanHitTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\QuiverTeamBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\page\WeatherPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\HideSeek.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\GameTeam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkHorsePet.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\events\EvolutionPostEvolveEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\kits\KitGladiator.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\entities\TugCow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\kits\KitSurvivorKnight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDoubleJumpHorse.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\event\staffoscars\StaffOscarsModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\event\kits\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\structure\tower\TowerManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackArrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\dominate_data\CapturePointTDM.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\Survive10Tracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snake\kits\KitReverser.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\event\CakeWarsEatCakeEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\booster\GameBoosterManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\PlaceSkullEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\StrikeItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\perks\PerkMobPotions.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\four\Section4.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\perks\PerkPaintballRifle.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\magmacube\PerkFlameDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\DemonStatsTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\selectors\EvenTeamSelector.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\MushroomBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\WaveBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFlamingSword.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\Challenge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modes\OverpoweredSGTeams.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\KitUHC.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\baconbrawl\kits\KitPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellGrowthLiner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\displays\IronWizardDisplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\buildmavericks\BuildMavericks.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitSlamShot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\assassin\MobaAssassinShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSnowman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\battleroyale\BattleRoyale.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\BanPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\BuildData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\EditRotationButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkJump.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkNull.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\GoToNextGameCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\WeaponPowerUp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitBeserker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\general\HotJoiningManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\TowerAlert.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snake\Snake.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\medals\MedalData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaTotalHealthEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\events\HumanReviveEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\EvoKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\BattleBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sheep\kits\KitBeserker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\UHCTeams.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\squidshooters\SquidShooters.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\wolf\PerkWolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\Wave1.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\KitShotgun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\OptionsPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\DragonKingTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\custom\CustomBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\trackers\PrecisionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\Section6.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\barbarians\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkIncreaseBoosters.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PlayerKitApplyEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\SpellButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snowfight\kits\KitSportsman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\basketball\DataLoc.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\MinionType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobZombieSpawner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\events\FirstToSafepadEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\stat\HalfHeartHealStat.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\EXPForKillsModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\ExtraScoreboardData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\displays\BossDisplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\enderman\PerkEndermanTeleport.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\ui\VotingPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackArmouredMobs.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\progression\ui\MobaRoleShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\EatFirstMinuteTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\booster\BoosterPodium.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\rowena\SkillBombardment.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkSulphurBombEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modules\BorderModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\ItemGiverModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\Voteable.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\anticheatmetadata\GameInfoMetadata.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\kit\KitHumanArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\LillyPadBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snake\kits\KitSpeed.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\anath\SkillFlameDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\antixray\AntiXrayService.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\Halloween2016.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitHiderInfestor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSquidShotgun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWaterDamage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\WitherPathfinder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillAllOpposingStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\spider\SmashSpider.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkTakedown.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\event\EventGame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\ToggleAfkKickCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\kits\perks\PerkJumpsDisplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\snowman\PerkArcticAura.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\MapCrumbleModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSquidSwim.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\team\CakeTeam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkTNTArrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\WinMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\tools\ToolLine.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\SummonMinionEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\dana\SkillRally.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\pig\PerkPigZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\DistanceTraveledStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\villager\PerkSonicBoom.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\creeper\SmashCreeper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\magmacube\PerkMagmaBlast.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeWaveCrush.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\SoloGame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\buff\buffs\BuffRooting.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\general\CakeSpawnerModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\GameSummaryModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSpeed.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\entities\TugSheep.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitBomber.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\SpectatorCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\cow\DataCowCharge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\kits\KitThor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\perks\PerkPaintballShotgun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\GameVotingButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkDeadeye.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\ActivateSpellEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\GameMode.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\cow\SmashCow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\NextBestGameManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\PinataMasterTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitCow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\creeper\PerkCreeperExplode.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaShopMenu.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellSniper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\selectors\RatioSelector.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gametutorial\TutorialText.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\biff\SkillBiffDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeRedLightGreenLight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\zombie\PerkOvercharge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\devon\SkillTNTArrows.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\PerkBloodlust.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\events\ChallengeStartEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\HunterKillerStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\HeadHunterTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\larissa\HeroLarissa.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\page\MobPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\deathtag\DeathTag.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\MazeGenerator.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\kits\KitCow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackThrowMobs.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\hotbar\HotbarPageListener.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\MinecraftLeague.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\generator\Generator.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\kit\KitSorcerer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherWeb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\ModuleUltimate.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeKangarooJump.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengePunchThePig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\mazes\Maze1.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitNinja.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWoolCloud.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bob\SkillHappyTrees.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\Incendiary.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\ctf_data\Flag.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\chest\ChestLootItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SpecialWinStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\Build.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobCreeper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellRainbowBeam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\ai\MobaAI.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitEnderman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\kits\DefaultKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackFlame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\objectives\KillObjective.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\perks\PerkDirtCannon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitKnight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkEvade.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkMammoth.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\custom\RadiusCustomBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\KitBooster.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\MobaBossAttack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\AltarBuilderTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\GameCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaShopCategoryMenu.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDummy.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\five\Section5.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\BossAttack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobPumpkinPrince.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\MonsterMaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\EatAllCakesTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\TeamSuperSmash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeMiniOneInTheQuiver.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitVillager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\KitFighter.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\data\Bullet.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\witch\PerkBatWave.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\FoodForTheMassesStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\compass\CompassModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snowfight\kits\KitTactician.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\DumbledontStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\tutorial\TutorialPhaseHalloween.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modes\OverpoweredSGSolo.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\winstreak\WinStreakModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\ArmorPowerUp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSlam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\modes\CakeWarsDuos.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\MapCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherAttack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\displays\SnakeDisplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDisruptor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaShopCategory.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\capturepoint\CapturePointModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\lobby\legacy\LegacyGameLobbyManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modules\FurnaceLootModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\general\CakeBatModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\trackers\NoMeleeTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\DebugCommandExecutor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\mission\AirborneTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\squidshooters\kit\KitRetroSquid.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\kits\KitUndeadAlpha.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\Paintball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\DamageTakenStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\objects\GravityPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\larissa\SkillAquaCannon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\Beam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinWithoutLosingTeammateStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\SpellMenuPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\WinWithinTimeTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\events\PaintballEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaItemEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\forms\CreatureForm.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\FireGrenadeBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\GamesPlayedStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\hunter\MobaHunterShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\chicken\PerkEggGun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWoolBomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\PumpkinPlant.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellRainbowRoad.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\events\RoundStartEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\modes\OPCakeWars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\ChooseMapPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\Section.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\tools\ToolCircle.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\PowerUpItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\map\ItemMapRenderer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\BridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\SmokeBombPowerUp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\ivy\SkillHook.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\rowena\HeroRowena.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\stattrackers\PerfectionistTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\page\GroundPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitMagmaCube.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkQuickshot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\trackers\TrackerTNTThrown.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\RemoveAdminPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\rings\Ring.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkIronSkin.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\WaveBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\HeroSkillUseEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeReverseTag.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkSurefoot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snowfight\kits\KitSnowFight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\PerkTargetLazer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherMinion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\Molotov.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\valentines\Valentines.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeWaterHorror.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\FreeKitWinStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\ChestRefillEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkFlamingSwordEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\VariationManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellNapalm.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\slime\SmashSlime.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\events\PlayerChangeArenaEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobBlaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinWithSheepStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\VersionModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\phase\Phase1.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\Minion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\SnowmanWaveA.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\hattori\SkillNinjaBlade.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\RecoveryMasterStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\deathtag\kits\KitChaser.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\events\EvolutionEndEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\pig\PerkPigBaconBomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\structure\tower\TowerDestroyEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkBlockTossEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\KitAir.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\rejoin\PlayerRejoinGameEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\larissa\SkillAOEHeal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\CastleSiegeTNTManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\SurvivalGamesNewTeams.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\PlayGameMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkAxeThrower.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitSlime.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\event\VoteStartEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\mazes\Maze2.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SpleefBlockDestroyStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\MazeMobWaypoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\BridgePart.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\ChristmasNewAudio.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\generator\GeneratorCollectEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSharpshooter.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\objective\ObjectiveManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\TeamSkywars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkArrowRebound.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillsWithinGameStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\slime\PerkSlimeSlam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TimeInGameStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\OptionsShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gametutorial\GameTutorial.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\StandardGameplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\OneVThreeStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\SmashKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\OreVeinEditorModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\RoundState.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\chat\ChatStatData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\LoseStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\selectors\FillToSelector.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TheMastersMasterStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\SafePad.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gametutorial\events\GameTutorialStartEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\MeowStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\CustomGunDamageEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkExplode.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\selectors\TeamSelector.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\BossFloor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkMadScientist.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\team\CakeTeamModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\snowman\PerkIcePath.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\QuiverTeams.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\hattori\HeroHattori.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\DrawGuessCorrectlyEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\ChristmasAudio.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDeathsGrasp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFletcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\Christmas.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\stats\RingStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\effect\DeathEffectData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\KitMachineGun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\rings\ElytraRings.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\UnbanPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\stattrackers\SpeediestBuilderizerTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillsWithConditionStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimateSkyWarrior.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkLazer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\BawkBawkBattles.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkElytraKnockback.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragons\MineplexDragon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bardolf\SkillWolfPounce.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSeismicHammer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\SleighHorse.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\witherskeleton\SmashWitherSkeleton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkConstructor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitNecromancer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkIronHook.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\PumpkinKing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\WhitelistedPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\capturepoint\CakePointModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\kits\KitLeaper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitSpider.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkShockingStrike.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\NightLivingDeadData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\PumpkinKing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\one\Section1.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\components\UHCSpeedMode.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\StopGameButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\game\QuiverPayload.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\guns\GunStats.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\zombie\PerkZombieBile.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\util\MobaUtil.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkPounceEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\SpellType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\CakeWars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitUndeadSummoner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\progression\MobaExperienceCalculateEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\modes\MobaMap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\GameStateChangeEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkHarden.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\trackers\PilotTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\objectives\ReturnSkullObjective.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\Radio.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\stattrackers\FirstBuildTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragons\kits\KitMarksman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragons\DragonsTeams.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWallStick.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\GameServerConfig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\modes\MobaHeroesValleyMap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\barbarians\Barbarians.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\CraftItemMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSmasher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\GemData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobPigZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaAmmoIncreaseEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\ParalympicsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBomberHG.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\Domination.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\overtime\OvertimeManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeDogsVersusCats.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\CompassPowerUp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\kit\KitMystic.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\BridgeAnimationType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\parts\Part1.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\AbsorptionFix.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\squid\PerkFishFlurry.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\LogicTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\golem\PerkFissure.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\events\EvolutionAttemptingTickEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\chest\ChestLootModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\kits\KitJumper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\runner\Runner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\BombToken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\ActivateNukeSpellEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobWitch.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinMapStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\BlockProtection.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BridgesSniperStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\Wave3.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaHPRegenEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkVanishing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\events\CaptureEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeVolleyPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\data\RecreationData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\dominate_data\Emerald.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\kits\KitTugLeaper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFlash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\general\BetaManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\five\SwitchParkour.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bob\SkillPaint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\anath\SkillMeteor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SeismicSlamStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\objective\GameObjective.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeArrowRampage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\kits\KitTugSmasher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\WitherGame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\kits\KitJetpack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\HolidayManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\island\CakeIslandModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\ExperienceStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\WaveBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkExplosionModifier.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\Wizards.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\GameStatisticsModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\parts\Part3.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\WizardSpellMenu.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\GetGoodStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\entities\TugChicken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\perks\PerkVoidSaver.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\lobby\current\NewGameLobbyManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkThrower.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\island\CakeIsland.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\KitCakeBuilder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeBlockLobbers.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkChicken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\BawkBawkBattlesSettings.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\perks\PerkPaladinBoost.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\TugItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaMeleeDamageEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\CakeSpecialItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitHumanWolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\kits\KitFarmerJump.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\MilkManTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeKingOfTheLadder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\four\MobDefense.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modules\TrackingCompassModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\GameVotingPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitNecromancer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\GWENAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\Sleigh.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\trackers\FlawlessTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\ChampionsCTF.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\biff\SkillWarHorse.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\larissa\SkillWaterDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkPowershot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\PixelNinjaTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\guns\Shotgun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\Wave1.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\TeamTower.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellFlash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\ivy\HeroIvy.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\structure\tower\Tower.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitSkeleton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\IceBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeletalhorse\PerkDeadlyBones.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\LinearUpgradeKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitUndeadZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\buff\buffs\BuffCrippled.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellIceShards.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\perks\PerkFireBurst.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\items\CakeWall.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitCreeper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\kits\KitTyper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengePickASide.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameWorldManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeFishingDay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRewind.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\SoloSuperSmash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWeb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SheepThiefStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\util\MobaParticles.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\capturepoint\CapturePoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaKillHealEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\Perk.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\trackers\EvoWinWithoutDyingTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBomber.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkBounceEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\mission\KillLastTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\GameVariation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\WhitelistButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\general\CakePlayerModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\RoleSelectEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSkeletalHorse.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\tools\ToolSquare.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\trackers\MedicStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\CreatureBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\ChampionsTDM.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\spleef\kits\KitSnowballer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\events\PerfectBuildEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snowfight\kits\KitMedic.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkPigCloak.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\chicken\PerkFlap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\ctf_data\PlayerCaptureFlagEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\stat\CollectFoodStat.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitChicken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\data\Bomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRopedArrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\PowerUp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\ui\CakeResourcePage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitSeekerRadar.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\DamageMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\LootTable.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\kits\KitMage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\MapZone.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TeamKillsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\objects\GravityHook.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\event\PlayerMasterAssassinEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\CakeItemModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\trackers\TNTStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\Draw.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\KillsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellManaBolt.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobMiniZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\turfforts\TurfForts.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\SurvivalGamesMapRenderer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\blaze\PerkFirefly.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\AlienInvasion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\DeathsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\guns\GunType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\kits\KitAssassin.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\trackers\KillsWhileEvolvingTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\ChallengeList.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\MenuPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\dana\SkillDanaDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\larissa\SkillStormHeal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\warrior\MobaWarriorShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobGhast.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeletalhorse\SmashSkeletalHorse.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\events\ReviveEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\GemSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitHorseman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\Snake.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\kits\KitAssassin.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\battleroyale\BattleRoyaleSupplyDrop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\objects\GravityBomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\gold\GoldManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\TeamGenerationEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gametutorial\events\GameTutorialPhaseEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\rowena\SkillLightArrows.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\winstreak\WinStreakSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\golem\PerkSeismicSlam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\minion\MinionManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\TypeAttemptEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellGust.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\BlockInfo.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackSnow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\pig\PerkPigBaconBounce.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\SpeedyBuildersTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\generator\GeneratorModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitSkyWarrior.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\UnbanButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBullsCharge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaSpeedEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeTeamItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkRemoveElytra.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\BlockTossData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\InterfaceMove.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\parts\Part.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\KitSpeeder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\DamageDealtStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaAbilityDamageEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\perk\PerkSlowSnowball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\TugOfWool.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitBlaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\kits\perks\PerkCraftman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\FurnaceMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\kit\KitWitchDoctor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\micro\Micro.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeShopModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\SnowmanMaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\dana\SkillPulseHeal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkAxeman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\events\ChallengeEndEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\dominate_data\CapturePoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBackstabKnockback.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeNetherItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\Wizard.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\common\SkillBow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkElytraBoost.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeBuildRace.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellSpeedUp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\npc\NpcManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\rejoin\RejoinModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBladeVortex.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\SnowmanWaypoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\micro\kits\KitFighter.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\UHCTeamsSpeed.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\command\MapRatingsCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\MobShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\guns\GunFactory.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snowfight\SnowFight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameFlagManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KaboomStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\ArcadeScoreboardLine.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\GameSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\trackers\TrackerBlastProof.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\basketball\kit\BasketballPlayerKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\kits\KitArtist.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\GunModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\FirstBloodEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\TypeWars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\TowerManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\valentines\ValItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\CastleSiegeHorseManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\golem\SmashGolem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\CaveGiant.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\deathtag\kits\KitAlphaChaser.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\kits\KitSlowball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWraith.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\spleef\SpleefDestroyBlockEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackSeismicWave.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\entities\TugEntity.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\perks\PerkOverrideValueCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\devon\HeroDevon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\SmashPerk.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\data\BuildData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\kits\KitRanger.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\Skyfall.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\tutorial\TutorialTypeWars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\BuildQuality.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sheep\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitSeekerLeaper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\DrawRound.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\rowena\SkillCombatDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bardolf\SkillSummonWolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\MineStrikeGunStats.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\SmashUltimate.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobSpiderSmasher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\ShardSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkHyper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\ComeAtMeBroStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\StartCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\worldmap\WorldMapModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\kits\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeleton\PerkBoneExplosion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\ClutchStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\squid\PerkSuperSquid.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\PerkWhirlpoolBlade.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\trackers\KillingSpreeTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\tutorial\TutorialHalloween2016.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\MineStrikeLastAliveKillStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\kit\KitBawksFood.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRangedBleeding.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitHumanPaladin.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSkySquid.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\BossBattles.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\gui\page\TimePage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\ArenaType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitDestructor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\ChristmasSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\SectionRegister.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSkullShot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\SuperSmash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\micro\kits\KitWorker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\TeamDeathmatch.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\events\TNTPreExplodeEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gametutorial\TutorialPhase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SlimySheepStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\trackers\Tracker6Kill.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\kit\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\pumpkin\PumpkinBossAI.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\module\ZombieGuardianModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkLeap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackShootArrows.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\IBlockRestorer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\BossFight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkCripple.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\DragonEscape.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeLavaRun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinFastStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\components\UHCFreezer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\IdleManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\events\EvolutionBeginEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\PlayerBoostRingEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkCleave.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFlameSlam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\Island.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherArrows.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitAssassin.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\CastleAssaultTDM.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\tutorial\TutorialPhaseGladiators.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\MobaBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\trackers\UntouchableTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\KitSniper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeEmpty.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\WizardSpellMenuShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\wither\attack\BossAttackEarthquake.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellKillEverything.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\TeamSkyfall.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BadHiderStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\HeroKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\DrawGuessStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\kits\KitTypeWarsBase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\SetCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\CapturePoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\SpeedBuilders.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\creeper\PerkCreeperElectricity.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\event\PerkBlockThrowEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\kits\SneakyAssassinKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\addons\SoupAddon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\general\ArrowKBManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimateBeserker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillAllOpposingMineStrikeRoundStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\PerkSmashStats.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\ChallengeTeam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\UHCSoloSpeed.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellSpectralArrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\witch\PerkWitchPotion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\CapturesStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\kits\KitTugArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\LavaBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\trackers\AbilityUseTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\dana\HeroDana.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\trap\CakeTNTTrap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\KitJouster.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GamePlayerManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\DefenderAI.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\devon\SkillInfinity.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\world\WorldData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\sheep\SmashSheep.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\evolve\PlatformToken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\magmacube\SmashMagmacube.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFood.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\trap\CakeTrapItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snake\events\TailGrowEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modules\SupplyDropModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\valentines\tutorial\TutorialPhaseValentines.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellAnvilDrop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\valentines\kit\KitMasterOfLove.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobPumpling.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\CastleSiegeNew.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\spider\PerkSpiderLeap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinWithoutOpeningChestStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TeamDeathsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\MobaPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitAxeman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\guns\Gun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkStrength.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\TeamArmorModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\StopCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRegeneration.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\util\MobaConstants.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\phase\BossPhase.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitBrawler.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\event\PerkDestructorBlockEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\baconbrawl\kits\KitMamaPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\kits\KitJumper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeRushPush.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\HomingSheepData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\SectionChallenge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\hotbar\HotbarInventory.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\TeamBeacon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\events\EvolutionAbilityUseEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\MilkRemoveEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\SonicBoomData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitSnowman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\custom\RandomCustomBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\turfforts\kits\KitInfiltrator.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\TimeInGameTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\animation\WoodBridgeAnimation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\kits\KitWarper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBlizzardFinn.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\ParticleData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\FissureData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\KillMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\WaveVictory.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\BoosterRing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherCompassScent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\Spell.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\Arena.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\ivy\SkillFloralLeap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\PlayerHeadModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellIcePrison.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\LobbyEnt.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\BossSnowmanPattern.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\TrainingGameModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\snowman\PerkDamageSnow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\cow\PerkCowMilkSpiral.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\titangiveaway\TitanGiveawayRepository.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\ore\OreHider.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDamageSet.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\trap\CakeBearTrap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\PlayerHeadButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSkeleton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\StrikeItemType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\ChooChooStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\compass\menu\page\CompassPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\KitAeronaught.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinWithoutDyingStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\CakeModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\parts\Part4.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDigger.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\SecondaryDamageManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\Bridge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\GameTeamModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\BouncingShadowTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\kits\KitKnight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\ore\OreObsfucation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobGiant.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\Quiver.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeFallingBlocks.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\TargetData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\event\PerkBlockGrabEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\equipment\DefusalKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellRumble.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\pig\SmashPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobGiant.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\ChallengeType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\BlocksMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\compass\menu\CompassMenu.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkIronShell.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSquidRifle.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\chicken\SmashChicken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeShopItem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\OwnAllBeaconsTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSlow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\perks\PerkIceBridge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\trackers\SurvivePast10thSafepadTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\ExperienceSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\three\CaveIn.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillFastStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBodySlam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\cow\PerkCowStampede.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\prepare\PrepareManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\WitherVariation.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\hp\HPManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\objectives\WitherObjective.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSparkler.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragons\kits\KitPyrotechnic.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\trackers\FirstToSafepadTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeZombieInfection.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\kits\KitWaller.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitWitherSkeleton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BloodThirstyStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\kits\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackFire.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\data\MobData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\ReturnToHubCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\SuperSmashDominate.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\kit\KitMage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\KitFire.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\basketball\data\ThrowData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellLightningStrike.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\NumberTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeCloudFall.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\trackers\SwiftKillTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitBlaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellImplode.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\event\staffoscars\RainbowSheep.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\MMMazes.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\modes\OverpoweredSGModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\present\Present.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snowfight\perks\PerkStoneWall.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSeismicSlamHG.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\wither\WitherBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitCreeper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\SurvivalGamesNew.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\evolve\EvolveManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\KitStunner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\two\IceMaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\two\Section2.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\kits\KitRobinHood.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\tutorial\TutorialGladiators.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\squid\PerkInkBlast.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkDoubleJumpEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\ElectrocutionStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\turfforts\mission\KillMidAirMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\FloorIsLavaTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\command\TauntCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\team\NamedTeamsModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\MasterAssassinStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\SpawnShieldModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellFireball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\HighExplosive.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\kits\KitArmorer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackMultiplier.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\PathfinderData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\compass\CompassAttemptTargetEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillsWithinTimeLimitStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkShadowmeld.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\barbarians\kits\KitBrute.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\golem\PerkIronHook.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\CooldownCalculateEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkLeapTackleHG.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\scoreboard\GameScoreboard.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\objectives\GearObjective.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\stat\HoeCraftingStat.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSlime.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitBomber.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\five\SnowmenKong.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\DragonEscapeData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\modes\OverpoweredBridge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\villager\SmashVillager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\kits\KitUndeadZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\zombie\SmashZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimatePerk.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\ChallengeData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\spleef\Spleef.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\VotingManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinAsTeamStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\VotingRepository.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellSummonWolves.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\GameType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellFrostBarrier.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\ChampionsDominate.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitCastleSiege.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\GameScore.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\EnderPearlModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\Skywars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\SetGameButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\events\AbilityUseEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\TargetLazerData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\wither\WitherBossOvertimeAI.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\hotbar\HotbarLayout.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\Wave5.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\ArcadeManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\Wave3.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\VeteranTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\other\ZombieWrapper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\boss\BossManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\event\CakeRotEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\kits\perk\PerkSeismicCow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\npc\BribedData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameSpectatorManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\three\Section3.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitHiderQuick.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\villager\PerkArts.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\QuiverScore.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinWithoutWearingArmorStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaHitArrowHealEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\WitherSkeletonTimer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\SpeedBuildersState.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\ShopManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\MobaClassic.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\SnowmanBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\speedbuilders\stattrackers\DependableTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeColorChange.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellTrapRune.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellWizardsCompass.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\BeamSource.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\Spell.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitUndeadArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobSkeletonArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\events\MonsterBumpPlayerEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\GroundData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\CryptBreaker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\biff\HeroBiff.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\snowman\PerkBlizzard.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\creatures\MobPrinceGuard.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSquidSniper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellWebShot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeBouncingBlock.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDestructor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\KillStreakData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\ui\CakeResourceStarPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\StatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitWitch.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\chicken\PerkChickenRocket.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\TheLongestShotStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\SoloSkywars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSniper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\items\CakeSafeTeleport.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameAchievementManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\SoloSkyfall.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\PureLuckStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\EliteArcherTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\lobby\LobbyManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snake\kits\KitInvulnerable.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\parts\Part2.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\EvoToken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWolfPet.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\MinionKillEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\squid\SmashSquid.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\Wave2.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\grenades\Grenade.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\NamedAudio.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\kits\KitFinn.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\SheepDropStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\anath\SkillBurnBeam.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkTripleJump.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\items\CakeDeployPlatform.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\Moba.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\DrawRoundEndEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\KitSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\KitDeadeye.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\KitEarth.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFallDamage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitChicken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeEggSmash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\blaze\SmashBlaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\deathtag\kits\KitRunnerTraitor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\squid\DataSquidGeyser.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\kits\perk\PerkCowBomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\ChickenMissileData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\tug\entities\TugPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitHumanKnight.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bob\SkillBeatTheDevil.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\one\CaveMaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\two\RockParkour.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\CastleAssault.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\StrikeGamesModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\KitMetal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\AchievementSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\antixray\AntiXrayModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\HunterOfTheYearStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\common\DashSkill.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\ServerUptimeManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitEnchanter.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\ObjectiveTNTSpawner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\mage\MobaMageShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\subclasses\TrapRune.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitGuardian.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\GravityObject.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkAeronaught.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\items\CakeSheep.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\TeamKing.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\AmmoGiveEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spellinterfaces\SpellClickEntity.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\basketball\Basketball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PlayerPrepareTeleportEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\SpawnRegenerationModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PlayerGameRespawnEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\powerups\PowerUpManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\GameComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitSheep.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameCreationManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\ModuleKillstreak.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\stats\AeronaughtStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\battleroyale\BattleRoyalePlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\MobaShopNPC.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\SuperSmashTraining.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\Kit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\KitAlchemist.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\WalkMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\KitWolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\KitDemolitionist.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\perks\SkywarsPerk.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\PlayerRespawnPoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\events\SmashActivateEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\kits\perks\PerkPaintballMachineGun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\WitherMinionManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\TeamAltar.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\CustomScoreboardModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\QuiverTeamModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BlockShreadStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\VariationType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\capturepoint\CapturePointCaptureEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\KitIce.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\HubClockManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBaconBlast.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkPinned.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\kits\KitRepulsor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gravity\objects\GravityDebris.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sheep\SheepGame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellMassSlow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeOreRun.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\MilkCow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\GamePrepareCountdownCommence.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\DebugCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\WaitForItStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PerkDoubleJumpEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\ChristmasCommon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\combattracker\CombatTrackerModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\ThrowableTNTModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackTaken.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\equipment\armor\Armor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\GameStatManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\events\TNTThrowEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\Arcade.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\Wave4.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\hp\MobaHPRegenEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaConditionImmunityEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\BanButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\chat\GameChatManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkHiltSmash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\enderman\PerkBlink.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\ArenaState.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\kits\KitPitcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\ModulePayload.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockback.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\kits\KitEscapeArtist.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\StartGameButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\EditRotationPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\PerkWaterSplash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\Loadout.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\battleroyale\BattleRoyaleSolo.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\kit\KitHumanEditor.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\micro\mission\Last2Tracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSkeletons.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeleton\PerkBarrage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\VoteRating.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\event\PerkLeapEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\ModuleCapturePoint.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\fountain\MobaFountain.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\ChampionsModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\turfforts\kits\KitShredder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\MeteorShowerData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\perk\PerkLifeSteal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BlockPlaceStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PlayerStateChangeEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\wave\WaveBoss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\RankedTeamGame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\build\kits\KitBuilder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\anath\SkillFireProjectile.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\runner\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\WinWithOneBiteTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\gladiators\trackers\BrawlerTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\Crumbleable.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\chest\ChestLootPool.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\event\PerkConstructorEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sheep\SheepData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\SnowmanWaveB.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitPyromancer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobSkeletonWarrior.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\Wave2.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFireArrows.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\CutCleanModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\forms\Form.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\AntiExpOrbModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\SafezoneModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\MinionSize.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\PlayerPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\HomingArrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\StaffKillMonitorManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\SnowmanMinion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaCDREffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\kits\KitGolem.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBlockRestorer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\GrabSkullEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\RevealStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeNavigationMaze.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherArrowBlind.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\kits\KitDigger.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\kits\KitSurvivorArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\snowman\SmashSnowman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\event\staffoscars\ChairData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\barbarians\kits\KitBomber.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\Vote.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\Evolution.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\stats\HoarderStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\valentines\tutorial\TutorialValentines.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeMilkACow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitBarrage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\HeadShotStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\kit\KitHumanMedic.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\kits\KitEvolveSpeed.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\micro\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\SetGamePage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\KitSorter.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\generator\GeneratorType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\deathtag\kits\KitRunnerArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\ChallengeStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\zombiesurvival\ZombieData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\witherskeleton\PerkWitherImage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\trackers\NoDamageWhileEvolvingTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackAttack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\SurfUpTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeTreasureDigger.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gametutorial\events\GameTutorialEndEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\trackers\LastStandStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitApple.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitSeekerTNT.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\GameMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\mazes\Maze3.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDefensiveStance.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\ChampionsKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spellinterfaces\SpellClickBlock.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\trackers\WinWithoutKillingTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spellinterfaces\SpellClick.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\dominate_data\PlayerData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\ProtectionUtil.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\misison\BowHorseKillTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\mobs\perks\PerkWebEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\SleighPart.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRadar.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\magmacube\PerkMagmaBoost.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wither\PlayerCopyWither.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BlockBreakStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\trackers\TrackerNoDamage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkKnockbackGive.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\tracker\TagMasterTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\HeroSkill.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\DeathBomberStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\displays\SlimeKingDisplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\game\QuiverKOTH.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\module\ModulePowerup.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeSmashOff.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDamageSnow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimateNecromancer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkFallModifier.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\components\UHCBorder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\kits\perks\PerkCooldownEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkQuickshotRobinHood.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bardolf\HeroBardolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skywars\kits\perks\PerkMagnetism.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitHumanMarksman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\necroinventory\NecroInventoryPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\SavingUpTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\TeamGame.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bossbattles\displays\SpiderDisplay.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\SmashGuardian.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bardolf\SkillFullMoon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\spider\PerkWebShot.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\kits\KitBodyBuilder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitchBroom.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellFirebomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragonescape\DragonScore.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobSpiderLeaper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\prepare\PrepareSelection.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\Minestrike.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\compass\menu\button\CompassButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\types\GameVote.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\perks\PerkOverrideLoadCommand.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\variation\wither\data\objectives\GrabSkullObjective.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\zombie\PerkDeathsGrasp.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\paintball\PlayerCopyPaintball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaCDRAmmoEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\PhaserProjectile.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\data\TeamCrystal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\OreGenerator.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\hattori\SkillNinjaDash.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\events\EntityLaunchEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\perks\MobPotion.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSeismicSlamOITQ.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\baconbrawl\BaconBrawl.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\alieninvasion\Alien.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\wizards\spells\SpellSpeedBoost.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\ArcadeFormat.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\slime\PerkSlimeRocket.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\bridge\kits\KitBrawler.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\perks\PerkSpreadsheetModule.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castleassault\kits\KitTank.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\champions\kits\KitBrute.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\trackers\NoAbilityTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\BossMobs.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\AssistsStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\draw\tools\Tool.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween2016\Crypt.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\castlesiegenew\kits\KitUndeadGhoul.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkHammerThrow.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\cow\PerkCowAngryHerd.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\guardian\SmashAnimationData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\NullKit.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\KitCakeArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\combattracker\CombatData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\skyfall\kits\perks\PerkSlowDown.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\witherskeleton\PerkWitherSkull.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\enderman\SmashEnderman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\snake\events\SlimeUpgradeEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\effect\DeathText.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\gamesummary\components\LevelUpSummaryComponent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\spells\SpellShrinkLiner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\KillButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\shop\CakeShopItemType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillReasonStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\baconbrawl\kits\KitSheepPig.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\Halloween.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\SurvivalGamesNewSolo.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\TeamChallenge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\milkcow\kits\perk\PerkCharge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\missions\EnchantItemMissionTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\hideseek\kits\KitHiderSwapper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\bob\HeroBob.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\OptionsButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\IcePathData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\PrivateServerShop.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkItemBreakdown.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobPigZombie.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\page\GiveAdminPage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeFastFood.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\general\MobaDamageManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\evolve\EvolveData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeAnvilDance.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WitherAssaultReviveTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkBlizzard.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\BehindEnemyLinesStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\KitBarbarian.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\Game.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\challenge\type\ChallengeMinecartDance.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\monstermaze\events\SafepadBuildEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimatePyromancer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\minion\MinionWave.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\evolution\kits\perks\PerkEvolveSpeedEVO.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmas\content\BossSnowman.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\map\ItemMapManager.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\sneakyassassins\kits\KitRevealer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\kits\KitCakeWarrior.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\WinWithoutBowStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\skeleton\SmashSkeleton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\ChooseMapButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\baconbrawl\kits\KitChrisPBacon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\typewars\tutorial\TutorialPhaseTypeWars.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkLooter.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobCreeper.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\events\SpecialEntityDeathEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\tracker\TowerDefenderTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\attack\AttackFire.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\progression\MobaLevelData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkLifestealArrows.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\ultimates\UltimateBarrage.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\spider\PerkNeedler.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\stats\KillEntityStatTracker.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\creatures\MobSkeletonArcher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\cakewars\item\items\CakeIceBridge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\data\ReboundData.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWitherMedicRefill.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\quiver\kits\KitNewNinja.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\deathtag\kits\KitRunnerBasher.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\TeamCrystal.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\items\equipment\armor\Kevlar.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\modes\MobaMapType.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minestrike\PlayerHeadshotEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\shop\effects\MobaHitArrowAmmoEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRecharge.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSnowball.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\mineware\effect\DeathEffect.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\ChristmasNew.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\baconbrawl\kits\perks\PerkCrispyBacon.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\enderman\PerkBlockToss.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\uhc\stat\LuckyMinerStat.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkVampire.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\dragons\Dragons.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkRevealer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\halloween\waves\Wave4.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkDoubleJump.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\managers\voting\types\VotableMap.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\kit\KitPlayer.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\minecraftleague\data\Spawner.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkWolfPack.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\events\PlayerDeathOutEvent.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\christmasnew\section\six\phase\Phase2.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\gui\privateServer\button\GiveAdminButton.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\blaze\PerkInferno.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\common\CaptureTheFlag.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkOreFinder.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\modules\compass\CompassEntry.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\smash\perks\wolf\SmashWolf.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\moba\kit\anath\HeroAnath.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\kit\perks\PerkSmokebomb.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\lobbers\BombLobbers.java +E:\Mineplex\Mineplex\Nautilus.Game.Arcade\src\nautilus\game\arcade\game\games\survivalgames\kit\necroinventory\NecroInventoryMenu.java diff --git a/Plugins[Modified]/app.xml b/Plugins[Modified]/app.xml index 32d87b5e..263b75dd 100644 --- a/Plugins[Modified]/app.xml +++ b/Plugins[Modified]/app.xml @@ -1,4 +1,3 @@ - 4.0.0 @@ -45,4 +44,4 @@ - + \ No newline at end of file diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar b/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar deleted file mode 100644 index 8264b8c0..00000000 Binary files a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar and /dev/null differ diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/_remote.repositories b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/_remote.repositories similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/1.0/_remote.repositories rename to Plugins[Modified]/lib/com/mineplex/spigot/1.0/_remote.repositories diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar.md5 b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.jar.md5 similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar.md5 rename to Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.jar.md5 diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar.sha1 b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.jar.sha1 similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.jar.sha1 rename to Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.jar.sha1 diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom similarity index 92% rename from Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom rename to Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom index 6e34fc2d..9c69935b 100644 --- a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom +++ b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom @@ -2,7 +2,7 @@ 4.0.0 - com.labalityowo + com.mineplex spigot 1.0 POM was created from install:install-file diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom.md5 b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom.md5 similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom.md5 rename to Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom.md5 diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom.sha1 b/Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom.sha1 similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/1.0/spigot-1.0.pom.sha1 rename to Plugins[Modified]/lib/com/mineplex/spigot/1.0/spigot-1.0.pom.sha1 diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml b/Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml similarity index 87% rename from Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml rename to Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml index ec570090..c3f38e12 100644 --- a/Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml +++ b/Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml @@ -1,6 +1,6 @@ - com.labalityowo + com.mineplex spigot 1.0 diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml.md5 b/Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml.md5 similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml.md5 rename to Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml.md5 diff --git a/Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml.sha1 b/Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml.sha1 similarity index 100% rename from Plugins[Modified]/lib/com/labalityowo/spigot/maven-metadata.xml.sha1 rename to Plugins[Modified]/lib/com/mineplex/spigot/maven-metadata.xml.sha1 diff --git a/Plugins[Modified]/mavericks-review-hub/plugin.yml b/Plugins[Modified]/mavericks-review-hub/plugin.yml new file mode 100644 index 00000000..ce83dbc1 --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/plugin.yml @@ -0,0 +1,3 @@ +name: Mavericks-Review-Hub +main: mineplex.mavericks.review.Hub +version: 0.1 \ No newline at end of file diff --git a/Plugins[Modified]/mavericks-review-hub/pom.xml b/Plugins[Modified]/mavericks-review-hub/pom.xml new file mode 100644 index 00000000..65404db9 --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + mavericks-review-hub + mavericks-review-hub + + + + ${project.groupId} + mineplex-minecraft-game-classcombat + ${project.version} + + + diff --git a/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java new file mode 100644 index 00000000..d6a44b1e --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java @@ -0,0 +1,154 @@ +package mineplex.mavericks.review; + +import net.minecraft.server.v1_8_R3.MinecraftServer; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; +import org.spigotmc.SpigotConfig; + +import mineplex.core.CustomTagFix; +import mineplex.core.FoodDupeFix; +import mineplex.core.PacketsInteractionFix; +import mineplex.core.account.CoreClientManager; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.antihack.AntiHack; +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.cosmetic.CosmeticManager; +import mineplex.core.creature.Creature; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.donation.DonationManager; +import mineplex.core.elo.EloManager; +import mineplex.core.friend.FriendManager; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.particle.king.CastleManager; +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.mavericks.MavericksApprovedRepository; +import mineplex.core.mavericks.MavericksBuildRepository; +import mineplex.core.memory.MemoryFix; +import mineplex.core.message.MessageManager; +import mineplex.core.monitor.LagMeter; +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; +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.thank.ThankManager; +import mineplex.core.treasure.TreasureManager; +import mineplex.core.updater.FileUpdater; +import mineplex.core.updater.Updater; +import mineplex.core.velocity.VelocityFix; +import mineplex.core.visibility.VisibilityManager; + +import static mineplex.core.Managers.require; + +/** + * Main JavaPlugin class for this plugin. Initializes the rest of this plugin. + */ +public class Hub extends JavaPlugin +{ + // Modules + private CoreClientManager _clientManager; + private DonationManager _donationManager; + + @Override + public void onEnable() + { + Bukkit.setSpawnRadius(0); + // Delete Old Games Folders + + // Configs + getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS); + getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY)); + saveConfig(); + + // Static Modules + CommandCenter.Initialize(this); + _clientManager = new CoreClientManager(this); + CommandCenter.Instance.setClientManager(_clientManager); + + ItemStackFactory.Initialize(this, false); + Recharge.Initialize(this); + require(VisibilityManager.class); + Give.Initialize(this); + + // Velocity Fix + new VelocityFix(this); + + _donationManager = require(DonationManager.class); + + PacketHandler packetHandler = require(PacketHandler.class); + + IncognitoManager incognito = new IncognitoManager(this, _clientManager, packetHandler); + PreferencesManager preferenceManager = new PreferencesManager(this, incognito, _clientManager); + + incognito.setPreferencesManager(preferenceManager); + + Creature creature = new Creature(this); + ServerStatusManager serverStatusManager = new ServerStatusManager(this, _clientManager, new LagMeter(this, _clientManager)); + Portal portal = new Portal(); + new FileUpdater(GenericServer.HUB); + + DisguiseManager disguiseManager = require(DisguiseManager.class); + + Punish punish = new Punish(this, _clientManager); + require(AntiHack.class); + + IgnoreManager ignoreManager = new IgnoreManager(this, _clientManager, preferenceManager, portal); + StatsManager statsManager = new StatsManager(this, _clientManager); + EloManager eloManager = new EloManager(this, _clientManager); + AchievementManager achievementManager = new AchievementManager(statsManager, _clientManager, _donationManager, incognito, eloManager); + FriendManager friendManager = require(FriendManager.class); + new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, friendManager, require(Chat.class)); + + BlockRestore blockRestore = require(BlockRestore.class); + + ProjectileManager projectileManager = new ProjectileManager(this); + HologramManager hologramManager = require(HologramManager.class); + + ServerConfiguration serverConfiguration = new ServerConfiguration(this, _clientManager); + + // Inventory + CastleManager castleManager = new CastleManager(this, _clientManager, hologramManager, false); + InventoryManager inventoryManager = new InventoryManager(this, _clientManager); + PetManager petManager = new PetManager(this, _clientManager, _donationManager, inventoryManager, disguiseManager, creature, blockRestore); + GadgetManager gadgetManager = require(GadgetManager.class); + ThankManager thankManager = new ThankManager(this, _clientManager, _donationManager); + BoosterManager boosterManager = new BoosterManager(this, serverConfiguration.getServerGroup().getBoosterGroup(), _clientManager, _donationManager, inventoryManager, thankManager); + CosmeticManager cosmeticManager = new CosmeticManager(this, _clientManager, _donationManager, inventoryManager, gadgetManager, petManager, require(TreasureManager.class), boosterManager, punish); + cosmeticManager.setInterfaceSlot(7); + cosmeticManager.disableTeamArmor(); + + new MemoryFix(this); + new CustomTagFix(this, packetHandler); + new PacketsInteractionFix(this, packetHandler); + new FoodDupeFix(this); + + new MavericksReviewManager(this, new MavericksBuildRepository(), new MavericksApprovedRepository()); + + require(ProfileCacheManager.class); + + new SimpleChatManager(this, _clientManager, achievementManager); + + // Updates + require(Updater.class); + + MinecraftServer.getServer().getPropertyManager().setProperty("debug", false); + SpigotConfig.debug = false; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/MavericksReviewManager.java b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/MavericksReviewManager.java new file mode 100644 index 00000000..1eb7889f --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/MavericksReviewManager.java @@ -0,0 +1,814 @@ +package mineplex.mavericks.review; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Consumer; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.EntityBlockFormEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCreativeEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.SchematicData; +import mineplex.core.common.util.BukkitFuture; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.worldgen.WorldGenCleanRoom; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.mavericks.MavericksApprovedRepository; +import mineplex.core.mavericks.MavericksBuildRepository; +import mineplex.core.mavericks.MavericksBuildWrapper; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import nautilus.game.arcade.ArcadeFormat; +/** + * The Mavericks Review Manager. Handles the review process. + */ +public class MavericksReviewManager extends MiniPlugin +{ + public static final Vector OFFSET_VECTOR = new Vector(8, -8, 0); + + private MavericksBuildRepository _repoBuilds; + private MavericksApprovedRepository _repoApprove; + + private Map _reviewers = new HashMap<>(); + + private Location _spawn; + private World _world; + + private List _processing = new ArrayList<>(); + + private List _reviewQueue = new ArrayList<>(); + + private final boolean DEBUG = false; + + private ItemStack _itemEnterReviewMode; + private ItemStack _itemExitReviewMode; + private ItemStack _itemNext; + private ItemStack _itemPrevious; + private ItemStack _itemApprove; + private ItemStack _itemDeny; + private ItemStack _itemFilter; + + public MavericksReviewManager(JavaPlugin plugin, MavericksBuildRepository repoBuilds, MavericksApprovedRepository repoApprove) + { + super("MavericksReviewManager", plugin); + + _repoBuilds = repoBuilds; + _repoApprove = repoApprove; + + _world = Bukkit.getWorlds().get(0); + _spawn = _world.getSpawnLocation().getBlock().getLocation(); + + //Apply Clean Room Generator to default world + ((CraftWorld)_world).getPopulators().addAll(new WorldGenCleanRoom().getDefaultPopulators(_world)); + _world.setGameRuleValue("keepInventory", "true"); + + + _itemEnterReviewMode = ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, C.cGreen + C.Bold + "Enter Review Mode"); + _itemExitReviewMode = ItemStackFactory.Instance.CreateStack(Material.COMPASS, (byte) 0, 1, C.cRed + C.Bold + "Exit Review Mode"); + _itemNext = ItemStackFactory.Instance.CreateStack(Material.ARROW, (byte) 0, 1, C.cGold + C.Bold + "Next Build"); + _itemPrevious = ItemStackFactory.Instance.CreateStack(Material.ARROW, (byte) 0, 1, C.cGold + C.Bold + "Previous Build"); + _itemApprove = ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 5, 1, C.cGreen + C.Bold + "Approve"); + _itemDeny = ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.cRed + C.Bold + "Deny"); + _itemFilter = ItemStackFactory.Instance.CreateStack(Material.HOPPER, (byte) 0, 1, C.cGold + C.Bold + "Filter Settings"); + } + + + private boolean isActionItem(ItemStack item) + { + if(_itemApprove.equals(item)) return true; + if(_itemDeny.equals(item)) return true; + if(_itemEnterReviewMode.equals(item)) return true; + if(_itemExitReviewMode.equals(item)) return true; + if(_itemFilter.equals(item)) return true; + if(_itemNext.equals(item)) return true; + if(_itemPrevious.equals(item)) return true; + + return false; + } + + @EventHandler + public void onGameMode(PlayerGameModeChangeEvent event) + { + boolean flying = event.getPlayer().isFlying(); + new BukkitRunnable() + { + public void run() + { + event.getPlayer().setAllowFlight(true); + event.getPlayer().setFlying(flying); + } + }.runTask(UtilServer.getPlugin()); + } + + @EventHandler + public void onForm(BlockFormEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onBlockFromTo(BlockFromToEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onSpread(BlockSpreadEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onEntityBlockFormEvent(EntityBlockFormEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onFade(BlockFadeEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onBlockIgnite(BlockIgniteEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onGrow(BlockGrowEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onBurn(BlockBurnEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void ignite(EntityCombustEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onRedstone(BlockRedstoneEvent event) + { + event.setNewCurrent(event.getOldCurrent()); + } + + @EventHandler + public void onDecay(LeavesDecayEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onIgnite(BlockIgniteEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onPhysics(BlockPhysicsEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onVehicleCollide(VehicleEntityCollisionEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onDamage(EntityDamageEvent event) + { + if(event.getCause() == DamageCause.VOID) return; + if(event.getCause() == DamageCause.CUSTOM) return; + if(event.getCause() == DamageCause.SUICIDE) return; + + if(event.getCause() == DamageCause.FIRE_TICK && event.getEntity() instanceof Player) + { + event.getEntity().setFireTicks(0); + } + + event.setCancelled(true); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + event.getPlayer().getInventory().removeItem(_itemApprove, _itemDeny, _itemExitReviewMode, _itemFilter, _itemNext, _itemPrevious); + + event.getPlayer().getInventory().setItem(0, _itemEnterReviewMode); + event.getPlayer().setGameMode(GameMode.ADVENTURE); + event.getPlayer().setAllowFlight(true); + event.getPlayer().setFlying(UtilEnt.isGrounded(event.getPlayer())); + } + + @EventHandler + public void onHunger(FoodLevelChangeEvent event) + { + event.setFoodLevel(20); + } + + @EventHandler + public void onWeather(WeatherChangeEvent event) + { + if(event.getWorld().getName().equals(_spawn.getWorld().getName())) + { + if(event.toWeatherState()) event.setCancelled(true); + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) + { + if(isActionItem(event.getCurrentItem()) || isActionItem(event.getCursor())) event.setCancelled(true); + } + + @EventHandler + public void onCreativeInventoryClick(InventoryCreativeEvent event) + { + if(isActionItem(event.getCurrentItem()) || isActionItem(event.getCursor())) event.setCancelled(true); + } + + @EventHandler + public void onDrop(PlayerDropItemEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if(isActionItem(event.getItem())) + { + event.setCancelled(true); + } + else + { + return; + } + + if(event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + + String name = event.getItem().getItemMeta().getDisplayName(); + + if(!Recharge.Instance.use(player, "MavericksReviewManager Action - " + name, 500, false, false)) return; + + if(_processing.contains(player)) + { + player.sendMessage(F.main(getName(), "Your action is still processing. Please wait...")); + player.playSound(player.getLocation(), Sound.NOTE_PIANO, 0.5f, 1); + return; + } + + _processing.add(player); + + if(event.getItem().equals(_itemEnterReviewMode)) + { + if(isInReviewMode(player)) + { + player.sendMessage(F.main(getName(), "You are already in " + F.item("review mode"))); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + return; + } + + ReviewData data = new ReviewData(player, getAvalibleLocation()); + + for(int i = 0; i < 9; i++) + { + player.getInventory().setItem(i, null); + } + + ItemStack back = _itemPrevious.clone(); + UtilInv.addDullEnchantment(back); + player.getInventory().setItem(0, back); + player.getInventory().setItem(1, _itemNext); + player.getInventory().setItem(3, _itemApprove); + player.getInventory().setItem(4, _itemDeny); + //player.getInventory().setItem(6, _itemFilter); + player.getInventory().setItem(8, _itemExitReviewMode); + + _reviewers.put(player, data); + pasteBuild(player, true); + } + else if(event.getItem().equals(_itemExitReviewMode)) + { + if(!isInReviewMode(player)) + { + player.sendMessage(F.main(getName(), "You are not currently in " + F.item("review mode"))); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + return; + } + + for(int i = 0; i < 9; i++) + { + player.getInventory().setItem(i, null); + } + player.getInventory().setItem(0, _itemEnterReviewMode); + + _reviewers.remove(player); + player.teleport(_spawn); + + _processing.remove(player); + } + + else if(!isInReviewMode(player)) + { + player.sendMessage(F.main(getName(), "Invalid action!")); + player.sendMessage(F.main(getName(), "You are not currently in " + F.item("review mode"))); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + return; + } + else if(event.getItem().equals(_itemApprove)) + { + ReviewData reviewData = _reviewers.get(player); + MavericksBuildWrapper data = reviewData.getData(); + if(data == null) + { + player.sendMessage(F.main(getName(), "Invalid action!")); + player.sendMessage(F.main(getName(), "You are currently not reviewing a build.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + return; + } + + if(data.isReviewed()) + { + player.sendMessage(F.main(getName(), "This build has already been reviewed!")); + player.sendMessage(F.main(getName(), "Contact the tech wizards if you want to change the")); + player.sendMessage(F.main(getName(), "state of the already reviewed build.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + return; + } + + _repoApprove.add(data, player.getUniqueId()).thenCompose(BukkitFuture.accept((success) -> + { + if(success) + { + player.sendMessage(F.main(getName(), "Marked build as " + F.color("approved", C.cGreen) + ".")); + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 0); + + + _repoBuilds.setReviewed(_reviewers.get(player).getData().getBuildId(), true).thenCompose(BukkitFuture.accept((success2) -> + { + if(success2) + { + data.setReviewed(true); + player.sendMessage(F.main(getName(), "Marked build as " + F.item("processed") + ".")); + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 0); + player.sendMessage(F.main(getName(), "Loading next build...")); + clear(reviewData); + pasteBuild(player, true); + } + else + { + player.sendMessage(F.main(getName(), "Unable to mark the build as " + F.item("processed") + "!")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + } + _processing.remove(player); + })); + + } + else + { + player.sendMessage(F.main(getName(), "Unable to mark the build as " + F.color("approved", C.cGreen) + "!")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + } + })); + } + else if(event.getItem().equals(_itemDeny)) + { + MavericksBuildWrapper data = _reviewers.get(player).getData(); + if(data == null) + { + player.sendMessage(F.main(getName(), "Invalid action!")); + player.sendMessage(F.main(getName(), "You are currently not reviewing a build.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + return; + } + + if(data.isReviewed()) + { + player.sendMessage(F.main(getName(), "This build has already been")); + player.sendMessage(F.main(getName(), "reviewed! Contact the tech wizards")); + player.sendMessage(F.main(getName(), "if you want to change the state of")); + player.sendMessage(F.main(getName(), "the already reviewed build.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + return; + } + + _repoBuilds.setReviewed(_reviewers.get(player).getData().getBuildId(), true).thenCompose(BukkitFuture.accept((success) -> + { + if(success) + { + data.setReviewed(true); + player.sendMessage(F.main(getName(), "Marked build as " + F.color("denied", C.cRed) + ".")); + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 0); + player.sendMessage(F.main(getName(), "Loading next build...")); + clear(_reviewers.get(player)); + pasteBuild(player, true); + } + else + { + player.sendMessage(F.main(getName(), "Unable to mark the build as " + F.color("denied", C.cRed) + "!")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + } + _processing.remove(player); + })); + } + else if(event.getItem().equals(_itemFilter)) + { + player.sendMessage(F.main(getName(), "Not yet implemented.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + } + else if(event.getItem().equals(_itemNext)) + { + pasteBuild(player, true); + } + else if(event.getItem().equals(_itemPrevious)) + { + pasteBuild(player, false); + } + } + + public void pasteBuild(Player player, boolean next) + { + ReviewData review = _reviewers.get(player); + if(review == null) + { + player.sendMessage(F.main(getName(), "Invalid action!")); + player.sendMessage(F.main(getName(), "You are not currently in " + F.item("review mode"))); + _processing.remove(player); + return; + } + + MavericksBuildWrapper data = null; + if(next) + { + data = review.getNext(); + } + else + { + data = review.getPrevious(); + } + if(!next && data == null) + { + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.5f); + player.sendMessage(F.main(getName(), "No previous builds available")); + ItemStack back = player.getInventory().getItem(0).clone(); + UtilInv.addDullEnchantment(back); + player.getInventory().setItem(0, back); + _processing.remove(player); + return; + } + if(next && data == null) + { + player.sendMessage(F.main(getName(), "Pulling new data, please wait...")); + getNext((pulledData) -> + { + if(pulledData == null) + { + player.sendMessage(F.main(getName(), "No new data was found.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0); + _processing.remove(player); + } + else + { + if(DEBUG) Bukkit.broadcastMessage("Displaying from DB -2"); + try { + player.getInventory().setItem(0, _itemPrevious); + display(player, review, pulledData); + } catch(Exception e) + { + e.printStackTrace(); + _processing.remove(player); + } + } + }); + } + if(data != null) + { + if(DEBUG) Bukkit.broadcastMessage("Displaying fast"); + display(player, review, data); + player.getInventory().setItem(0, _itemPrevious); + } + } + + private void clear(ReviewData review) + { + if(review == null) return; + + UtilBlock.startQuickRecording(); + //Clear old blocks for stuff like lava and so on. + for(Block b : UtilBlock.getInBoundingBox(review.getAreaMin(), review.getAreaMax())) + { + UtilBlock.setQuick(_world, b.getX(), b.getY(), b.getZ(), 0, (byte) 0); + } + Location a = review.getAreaMin(); + Location b = review.getAreaMax(); + b.setY(a.getY()); + // Floor + for(Block block : UtilBlock.getInBoundingBox(a, b, false)) + { + UtilBlock.setQuick(_world, block.getX(), block.getY(), block.getZ(), 95, (byte) 1); + } + // Walls/edge + for(Block block : UtilBlock.getInBoundingBox(a, b, false, true, true, false)) + { + UtilBlock.setQuick(_world, block.getX(), block.getY()+1, block.getZ(), 95, (byte) 0); + } + + UtilBlock.stopQuickRecording(); + List list = review.getEntitiesInArea(); + for(Entity e : list) + { + e.remove(); + } + if(DEBUG) Bukkit.broadcastMessage("Cleared " + list.size() + " entities in area"); + } + + private void display(Player player, ReviewData review, MavericksBuildWrapper data) + { + Location loc = review.getLoc(); + Location paste = review.getAreaMin().add(1, 1, 1); + loc.setDirection(OFFSET_VECTOR.clone().add(new Vector(0, 4, 0))); + + clear(review); + + if(DEBUG) Bukkit.broadcastMessage("Trying to parse from " + data.getDateStamp()); + if(DEBUG) Bukkit.broadcastMessage("SBytes: " + data.getSchematicBytes().length + ", Schematic: " + data.getSchematic()); + Schematic schematic = data.getSchematic(); + + SchematicData pasteData = schematic.paste(paste, false, false); + for(Entity e : pasteData.getEntities()) + { + if(e instanceof Item) + { + //Don't despawn + e.setTicksLived(32768); + } + else + { + UtilEnt.vegetate(e, true); + UtilEnt.ghost(e, true, false); + } + } + player.sendMessage(ArcadeFormat.Line); + + String key = C.cGreen + C.Bold; + String value = C.cYellow + C.Bold; + SimpleDateFormat dformat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss z"); + + player.sendMessage(key + "BuildId: " + value + data.getBuildId()); + player.sendMessage(key + "Creator: " + value + data.getUUID()); + player.sendMessage(key + "Last C Name: " + value + (data.hasNameSet() ? data.getName() : C.Italics + "Not Avalible")); + player.sendMessage(key + "Word: " + value + data.getTheme()); + player.sendMessage(key + "Place: " + value + (data.getPlace() + 1)); + player.sendMessage(key + "Points: " + value + data.getPoints()); + player.sendMessage(key + "Date: " + value + dformat.format(new Date(data.getDateStamp()))); + player.sendMessage(key + "Reviewed: " + value + data.isReviewed()); + + player.sendMessage(ArcadeFormat.Line); + + player.setVelocity(new Vector(0,0,0)); + player.setAllowFlight(true); + player.setFlying(true); + player.teleport(loc); + + review.setData(data); + + _processing.remove(player); + } + + + @EventHandler + public void onUpdateParticles(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) return; + + for(ReviewData data : _reviewers.values()) + { + if(data.getData() == null) continue; + + if(!data.getData().hasParticles()) continue; + + for(Entry e : data.getData().getParticles().entrySet()) + { + Location loc = data.getAreaMin().add(1, 1, 1).add(e.getKey()); + + ParticleType type = e.getValue(); + + int amount = 8; + + if (type == ParticleType.HUGE_EXPLOSION || + type == ParticleType.LARGE_EXPLODE || + type == ParticleType.NOTE) + amount = 1; + + UtilParticle.PlayParticleToAll(type, loc, 0.4f, 0.4f, 0.4f, 0, amount, ViewDist.LONG); + } + } + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + ReviewData data = _reviewers.get(event.getPlayer()); + if(data != null) + { + for(Entity e : data.getEntitiesInArea()) e.remove(); + + for(Block b : UtilBlock.getInBoundingBox(data.getAreaMin(), data.getAreaMax())) + { + UtilBlock.setQuick(_world, b.getX(), b.getY(), b.getZ(), 0, (byte) 0); + } + } + exitReviewMode(event.getPlayer()); + } + + public boolean isInReviewMode(Player player) + { + return _reviewers.containsKey(player); + } + + public void enterReviewMode(Player player) + { + if(isInReviewMode(player)) return; + } + + public void exitReviewMode(Player player) + { + if(!isInReviewMode(player)) return; + + _reviewers.remove(player); + } + + public Location getAvalibleLocation() + { + for(int i = 0; i < 500; i++) + { + Location loc = _spawn.clone().add(100*i, 0, 0); + loc.setY(200); + if(isTaken(loc)) continue; + return loc; + } + return null; + } + + private boolean isTaken(Location loc) + { + for(ReviewData data : _reviewers.values()) + { + if(data.getData() == null) continue; + if(data.getLoc().equals(loc)) return true; + } + return false; + } + + private boolean isTaken(MavericksBuildWrapper wrapper) + { + if(wrapper.isReviewed()) return true; + for(ReviewData data : _reviewers.values()) + { + if(data.containsData(wrapper)) return true; +// if(data.getData() == null) continue; +// if(data.getData().equals(wrapper)) return true; + } + return false; + } + + public void getNext(Consumer consumer) + { + pullQueue(getNextIndex(), consumer); + } + + public int getNextIndex() + { + for(int i = 0; i < _reviewQueue.size(); i++) + { + MavericksBuildWrapper wrapper = _reviewQueue.get(i); + if(isTaken(wrapper)) continue; + if(wrapper.isReviewed()) continue; + if(wrapper.getSchematic() == null) continue; + if(DEBUG) Bukkit.broadcastMessage("Found avalible index: " + i); + return i; + } + if(DEBUG) Bukkit.broadcastMessage("Found no avalible indexes, returning next one: " + _reviewQueue.size()); + return _reviewQueue.size(); + } + + public void pullQueue(int index, Consumer consumer) + { + if(_reviewQueue.size() > index) + { + consumer.accept(_reviewQueue.get(index)); + if(DEBUG) Bukkit.broadcastMessage("Local queue is bigger then index"); + return; + } + + int offset = 0; + for(MavericksBuildWrapper build : _reviewQueue) + { + if(!build.isReviewed()) offset++; + } + + if(DEBUG) Bukkit.broadcastMessage("Pulling from DB, limit: " + (index-_reviewQueue.size()+1) + ", offset " + offset); + + _repoBuilds.getToReview(true, index-_reviewQueue.size()+1, offset).thenCompose(BukkitFuture.accept((list) -> + { + if(DEBUG) Bukkit.broadcastMessage("Retrived " + list.size() + " entries from DB"); + + + + _reviewQueue.addAll(list); + if(_reviewQueue.size() > index) + { + if(DEBUG) Bukkit.broadcastMessage("Found new entry to process!"); + + consumer.accept(_reviewQueue.get(index)); + } + else + { + if(DEBUG) Bukkit.broadcastMessage("Still not enough though"); + + consumer.accept(null); + } + })); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/ReviewData.java b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/ReviewData.java new file mode 100644 index 00000000..7df92561 --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/ReviewData.java @@ -0,0 +1,131 @@ +package mineplex.mavericks.review; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import mineplex.core.mavericks.MavericksBuildWrapper; +/** + * A simple wrapper class used to hold build data related to a location and player. + */ +public class ReviewData +{ + private Player _player; + private MavericksBuildWrapper _data; + private List _logg = new ArrayList<>(); + private Location _loc; + + public ReviewData(Player player, Location loc) + { + _player = player; + _loc = loc.getBlock().getLocation().add(0.5, 0, 0.5); + } + + public Player getPlayer() + { + return _player; + } + + public Location getLoc() + { + return _loc.clone(); + } + + public MavericksBuildWrapper getData() + { + return _data; + } + + public void setData(MavericksBuildWrapper data) + { + if (!_logg.contains(_data)) + { + _logg.add(_data); + } + if (!_logg.contains(data)) + { + _logg.add(data); + } + _data = data; + } + + public MavericksBuildWrapper getPrevious() + { + int index = _logg.indexOf(_data); + + if (index <= 0) + { + return null; + } + + MavericksBuildWrapper data = _logg.get(index-1); + if (data != null && data.isReviewed()) + { + _data = data; + return getPrevious(); + } + return data; + } + + public MavericksBuildWrapper getNext() + { + int index = _logg.indexOf(_data); + + if (index == -1) + { + return null; + } + if (index+1 >= _logg.size()) + { + return null; + } + + MavericksBuildWrapper data = _logg.get(index+1); + if (data != null && data.isReviewed()) + { + _data = data; + return getNext(); + } + return data; + } + + public boolean containsData(MavericksBuildWrapper data) + { + return _logg.contains(data); + } + + public Location getAreaMin() + { + return _loc.getBlock().getLocation().add(MavericksReviewManager.OFFSET_VECTOR).subtract(1, 1, 12); + } + + public Location getAreaMax() + { + return getAreaMin().add(24, 28, 24); + } + + public List getEntitiesInArea() + { + List list = new ArrayList<>(); + for (Entity e : _loc.getWorld().getEntities()) + { + if (e instanceof Player) + { + continue; + } + if (isInsideArea(e.getLocation())) + { + list.add(e); + } + } + return list; + } + + public boolean isInsideArea(Location loc) + { + return loc.toVector().isInAABB(getAreaMin().toVector(), getAreaMax().toVector()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/SimpleChatManager.java b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/SimpleChatManager.java new file mode 100644 index 00000000..634a2344 --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/src/mineplex/mavericks/review/SimpleChatManager.java @@ -0,0 +1,86 @@ +package mineplex.mavericks.review; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.common.util.UtilServer; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.HoverEvent.Action; +import net.md_5.bungee.api.chat.TextComponent; + +/** + * A simple manager for formating the chat + */ +public class SimpleChatManager extends MiniPlugin +{ + private CoreClientManager _coreClientManager; + private AchievementManager _achievementManager; + + public SimpleChatManager(JavaPlugin plugin, CoreClientManager coreClientManager, AchievementManager achivementManager) + { + super("Chat Format Manager", plugin); + _coreClientManager = coreClientManager; + _achievementManager = achivementManager; + } + + @EventHandler + public void PlayerChat(AsyncPlayerChatEvent event) + { + if (event.isCancelled()) + { + return; + } + + Player player = event.getPlayer(); + String playerName = player.getName(); + + //Level Prefix + String levelStr = _achievementManager.getMineplexLevel(player); + + PermissionGroup group = _coreClientManager.Get(player).getRealOrDisguisedPrimaryGroup(); + + //Rank Prefix + String rankStr = ""; + if (!group.getDisplay(false, false, false, false).isEmpty()) + { + rankStr = group.getDisplay(true, true, true, false) + " "; + } + + TextComponent rankComponent = new TextComponent(rankStr); + TextComponent playerNameText = new TextComponent(ChatColor.YELLOW + playerName); + TextComponent component = new TextComponent(); + + rankComponent.setHoverEvent(new HoverEvent(Action.SHOW_TEXT, new ComponentBuilder(group.getDisplay(true, true, true, true) + ChatColor.WHITE + "\n" + group.getDescription()).create())); + + component.setText(levelStr); + component.addExtra(rankComponent); + component.addExtra(playerNameText); + component.addExtra(" " + ChatColor.WHITE + event.getMessage()); + +// JsonMessage jsonMessage = new JsonMessage(levelStr) +// .extra(JSONObject.escape(rankStr)).hover("show_text", rank.getColor() + rank.getTag(true, true) + ChatColor.WHITE + "\n" + rank.getDescription()) +// .add(JSONObject.escape(C.cYellow + playerName + " " + ChatColor.WHITE + event.getMessage())); + + for (Player other : UtilServer.getPlayers()) + { + + // event.setMessage(event.getMessage()); + // event.setFormat(levelStr + rankStr + C.cYellow + playerName + " " + C.cWhite + "%2$s"); + if (!event.isCancelled()) + { + other.spigot().sendMessage(component); + } + } + Bukkit.getConsoleSender().sendMessage(component.toLegacyText()); + event.setCancelled(true); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mavericks-review-hub/src/nautilus/game/arcade/ArcadeFormat.java b/Plugins[Modified]/mavericks-review-hub/src/nautilus/game/arcade/ArcadeFormat.java new file mode 100644 index 00000000..5e2fb459 --- /dev/null +++ b/Plugins[Modified]/mavericks-review-hub/src/nautilus/game/arcade/ArcadeFormat.java @@ -0,0 +1,11 @@ +package nautilus.game.arcade; + +import mineplex.core.common.util.C; + +/** + * Copy from {@link nautilus.game.arcade.ArcadeFormat} + */ +public class ArcadeFormat +{ + public static String Line = C.cDGreen + C.Strike + "============================================="; +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/plugin.yml b/Plugins[Modified]/mineplex-game-gemhunters/plugin.yml new file mode 100644 index 00000000..a5af44c6 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/plugin.yml @@ -0,0 +1,3 @@ +name: GemHunters +main: mineplex.gemhunters.GemHunters +version: 0.1 diff --git a/Plugins[Modified]/mineplex-game-gemhunters/pom.xml b/Plugins[Modified]/mineplex-game-gemhunters/pom.xml new file mode 100644 index 00000000..16129c05 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + GemHunters + mineplex-game-gemhunters + + + + ${project.groupId} + mineplex-core + ${project.version} + + + ${project.groupId} + mineplex-minecraft-game-core + ${project.version} + + + \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java new file mode 100644 index 00000000..a5dab37f --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java @@ -0,0 +1,324 @@ +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.account.CoreClientManager; +import mineplex.core.achievement.AchievementManager; +//import mineplex.core.antihack.AntiHack; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.boosters.BoosterManager; +import mineplex.core.chat.Chat; +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.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.disguise.playerdisguise.PlayerDisguiseManager; +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.gadget.gadgets.particle.king.CastleManager; +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.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.preferences.PreferencesManager; +import mineplex.core.projectile.ProjectileManager; +import mineplex.core.punish.Punish; +import mineplex.core.recharge.Recharge; +import mineplex.core.report.ReportManager; +import mineplex.core.report.ReportPlugin; +import mineplex.core.serverConfig.ServerConfiguration; +import mineplex.core.stats.StatsManager; +import mineplex.core.status.ServerStatusManager; +import mineplex.core.task.TaskManager; +import mineplex.core.teleport.Teleport; +import mineplex.core.texttutorial.TextTutorialManager; +import mineplex.core.thank.ThankManager; +import mineplex.core.titles.Titles; +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.chat.ChatModule; +import mineplex.gemhunters.death.DeathModule; +import mineplex.gemhunters.death.quitnpc.QuitNPCModule; +import mineplex.gemhunters.economy.CashOutModule; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.join.JoinModule; +import mineplex.gemhunters.loot.InventoryModule; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.map.ItemMapModule; +import mineplex.gemhunters.moderation.ModerationModule; +import mineplex.gemhunters.mount.MountModule; +import mineplex.gemhunters.persistence.PersistenceModule; +import mineplex.gemhunters.playerstatus.PlayerStatusModule; +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.tutorial.GemHuntersTutorial; +import mineplex.gemhunters.world.Leaderboards; +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
+ * + * 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); + + // ItemStacks + ItemStackFactory.Initialize(this, false); + + // Delayed Tasks + DelayedTask.Initialize(this); + + // Recharge + Recharge.Initialize(this); + + // Visibility + require(VisibilityManager.class); + + // 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(GenericServer.HUB); + + // Punish + Punish punish = new Punish(this, clientManager); + + // Disguises + DisguiseManager disguiseManager = require(DisguiseManager.class); + require(PlayerDisguiseManager.class); + + // Creatures + Creature creature = new Creature(this); + creature.SetDisableCustomDrops(true); + + // The old classic Damage Manager + DamageManager damageManager = new DamageManager(this, require(CombatManager.class), new NpcManager(this, creature), disguiseManager, new ConditionManager(this)); + damageManager.SetEnabled(false); + + // GWEN + /* + AntiHack antiHack = require(AntiHack.class); + Bukkit.getScheduler().runTask(this, () -> + { + antiHack.setStrict(true); + 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 + new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, require(FriendManager.class), require(Chat.class)); + + // Parties + new PartyManager(); + + // Communities + require(CommunityManager.class); + + // 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 = require(HologramManager.class); + + // Menus + new MenuManager(this); + + // Gadgets + CastleManager castleManager = new CastleManager(this, clientManager, hologramManager, false); + PetManager petManager = new PetManager(this, clientManager, donationManager, inventoryManager, disguiseManager, creature, blockRestore); + ProjectileManager projectileManager = new ProjectileManager(this); + GadgetManager gadgetManager = require(GadgetManager.class); + 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, petManager, null, boosterManager, punish); + + cosmeticManager.setActive(false); + cosmeticManager.setHideParticles(true); + cosmeticManager.disableTeamArmor(); + + // Tutorials + TextTutorialManager tutorialManager = new TextTutorialManager(this, donationManager, new TaskManager(this, clientManager)); + tutorialManager.addTutorial(new GemHuntersTutorial()); + + require(Titles.class).forceDisable(); + + // 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(CashOutModule.class); + require(ChatModule.class); + require(DeathModule.class); + require(EconomyModule.class); + require(InventoryModule.class); + require(LootModule.class); + require(ItemMapModule.class); + require(JoinModule.class); + require(ModerationModule.class); + require(MountModule.class); + require(PersistenceModule.class); + require(PlayerStatusModule.class); + require(QuestModule.class); + require(QuitNPCModule.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 Leaderboards(); + + // UpdateEvent!!! + require(Updater.class); + + // 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); + } + + @Override + public void onDisable() + { + getServer().getPluginManager().callEvent(new ServerShutdownEvent(this)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/beta/BetaModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/beta/BetaModule.java new file mode 100644 index 00000000..03490754 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/beta/BetaModule.java @@ -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/viewforum/2369449/m/11929946", + "Thank you for playing Gem Hunters!", + "Safezones are marked as green areas on your map!", + "Players that have super valuable items show up on your map!", + "Tell us what you want added next by voting on our features Trello! https://trello.com/b/ia1kjwcx", + "The highest value player is shown on the map as a red pointer." + }; + + private int _lastIndex; + + private BetaModule() + { + super("Beta"); + } + + @EventHandler + public void announce(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; + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java new file mode 100644 index 00000000..ad154fe0 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java @@ -0,0 +1,111 @@ +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.account.permissions.PermissionGroup; +import mineplex.core.chat.Chat; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.progression.ProgressionModule; + +/** + * This module handles player chat. + */ +@ReflectivelyCreateMiniPlugin +public class ChatModule extends MiniPlugin +{ + + private final CoreClientManager _clientManager; + private final Chat _chat; + private final EconomyModule _economy; + private final PartyManager _party; + private final ProgressionModule _progression; + + private ChatModule() + { + super("Chat"); + + _clientManager = require(CoreClientManager.class); + _chat = require(Chat.class); + _economy = require(EconomyModule.class); + _party = require(PartyManager.class); + _progression = require(ProgressionModule.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(); + + PermissionGroup group = _clientManager.Get(player).getRealOrDisguisedPrimaryGroup(); + String rankString = group.getDisplay(false, false, false, false).isEmpty() ? "" : group.getDisplay(true, true, true, false); + + // Create a message that follows the rest of the network's chat format + String message = (rankString + " " + C.cYellow + playerName + " "); + + // We will handle the broadcast + event.setCancelled(true); + + if (event.getMessage().charAt(0) == '@') + { + Party party = _party.getPartyByPlayer(player); + if (party != null) + { + if (event.getMessage().length() > 1) + { + event.setMessage(event.getMessage().substring(1, event.getMessage().length()).trim()); + message = C.cDPurpleB + "Party " + C.cWhiteB + playerName + " " + C.cPurple; + + event.getRecipients().removeIf(other -> !party.getMembers().contains(other)); + } + else + { + player.sendMessage(F.main("Party", "Where's the message?")); + } + } + } + else + { + message = _progression.getTitle(_economy.getGems(player)).getTitle() + " " + message + C.cWhite; + } + + message += _chat.filterMessage(player, event.getMessage()); + + message = message.trim(); + + for (Player other : event.getRecipients()) + { + other.sendMessage(message); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java new file mode 100644 index 00000000..ed5f9e55 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java @@ -0,0 +1,252 @@ +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.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Entity; +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.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.google.common.collect.Sets; + +import mineplex.core.Managers; +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.stats.StatsManager; +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.playerstatus.PlayerStatusModule; +import mineplex.gemhunters.playerstatus.PlayerStatusType; +import mineplex.gemhunters.spawn.SpawnModule; + +/** + * This module handles anything to do with a players death + */ +@ReflectivelyCreateMiniPlugin +public class DeathModule extends MiniPlugin +{ + + // Don't need to be dropped to avoid duplication. + private static final Set DISALLOWED_DROPS = Sets.newHashSet(Material.EMERALD, Material.MAP, Material.STAINED_GLASS_PANE); + private static final int DEATH_ANIMATION_TIME = 7000; + private static final int DEATH_ANIMATION_COUNTDOWN = 2000; + + private final PlayerStatusModule _playerStatus; + private final StatsManager _stats; + private final SpawnModule _spawn; + + private final Map _toRemove; + + private DeathModule() + { + super("Death"); + + _playerStatus = require(PlayerStatusModule.class); + _stats = require(StatsManager.class); + _spawn = require(SpawnModule.class); + + _toRemove = new HashMap<>(); + } + + @EventHandler + public void death(PlayerDeathEvent event) + { + Player player = event.getEntity(); + + // Stop the player dieing + player.setHealth(20); + player.setFoodLevel(20); + player.setExhaustion(0); + + // Record the stats + Player killer = player.getKiller(); + + if (killer != null) + { + _stats.incrementStat(killer, "Gem Hunters.Kills", 1); + } + + 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 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); + iterator.remove(); + 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); + ((CraftPlayer) player).getHandle().spectating = true; + player.setAllowFlight(true); + player.setFlying(true); + player.setGameMode(GameMode.CREATIVE); + + VisibilityManager vm = Managers.require(VisibilityManager.class); + for (Player other : Bukkit.getOnlinePlayers()) + { + vm.hidePlayer(other, player, "GH Respawning"); + } + + _playerStatus.setStatus(player, PlayerStatusType.DANGER, true); + } + + public void stopAnimation(Player player) + { + UtilTextMiddle.display(C.cGreenB + "RESPAWNED", "", 0, 20, 20, player); + ((CraftPlayer) player).getHandle().spectating = false; + player.setFlying(false); + player.setAllowFlight(false); + player.setGameMode(GameMode.SURVIVAL); + _spawn.teleportToSpawn(player); + + VisibilityManager vm = Managers.require(VisibilityManager.class); + for (Player other : Bukkit.getOnlinePlayers()) + { + vm.showPlayer(other, player, "GH Respawning"); + } + + PlayerCustomRespawnEvent event = new PlayerCustomRespawnEvent(player); + + UtilServer.CallEvent(event); + } + + @EventHandler + public void interact(PlayerInteractEvent event) + { + if (isRespawning(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void itemPickup(PlayerPickupItemEvent event) + { + if (isRespawning(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void blockBreak(BlockBreakEvent event) + { + if (isRespawning(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void blockPlace(BlockPlaceEvent event) + { + if (isRespawning(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void inventory(InventoryClickEvent event) + { + if (isRespawning(event.getWhoClicked())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void entityDamage(EntityDamageEvent event) + { + if (event instanceof EntityDamageByEntityEvent) + { + if (isRespawning(((EntityDamageByEntityEvent) event).getDamager())) + { + event.setCancelled(true); + } + } + + if (isRespawning(event.getEntity())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + _toRemove.remove(event.getPlayer().getUniqueId()); + } + + public boolean isRespawning(Entity player) + { + return _toRemove.containsKey(player.getUniqueId()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/PlayerCustomRespawnEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/PlayerCustomRespawnEvent.java new file mode 100644 index 00000000..e588841c --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/PlayerCustomRespawnEvent.java @@ -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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/QuitNPCDespawnEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/QuitNPCDespawnEvent.java new file mode 100644 index 00000000..8e4de19b --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/QuitNPCDespawnEvent.java @@ -0,0 +1,56 @@ +package mineplex.gemhunters.death.event; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import mineplex.gemhunters.death.quitnpc.QuitNPC; + +public class QuitNPCDespawnEvent extends Event implements Cancellable +{ + + private static final HandlerList HANDLERS = new HandlerList(); + + private final QuitNPC _npc; + private final boolean _pluginRemove; + private boolean _cancel; + + public QuitNPCDespawnEvent(QuitNPC npc, boolean pluginRemove) + { + _npc = npc; + _pluginRemove = pluginRemove; + } + + public QuitNPC getNpc() + { + return _npc; + } + + public boolean isPluginRemove() + { + return _pluginRemove; + } + + 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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/QuitNPCSpawnEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/QuitNPCSpawnEvent.java new file mode 100644 index 00000000..3908e169 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/QuitNPCSpawnEvent.java @@ -0,0 +1,42 @@ +package mineplex.gemhunters.death.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class QuitNPCSpawnEvent extends PlayerEvent implements Cancellable +{ + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean _cancel; + + public QuitNPCSpawnEvent(Player who) + { + super(who); + } + + 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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPC.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPC.java new file mode 100644 index 00000000..e3cc6d88 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPC.java @@ -0,0 +1,186 @@ +package mineplex.gemhunters.death.quitnpc; + +import mineplex.core.Managers; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +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.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.utils.UtilGameProfile; +import mineplex.gemhunters.death.event.QuitNPCDespawnEvent; +import mineplex.gemhunters.economy.EconomyModule; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import java.util.UUID; + +public class QuitNPC implements Listener +{ + // Managers + private final DisguiseManager _disguise; + + // Time + private final long _start; + private final long _quitMills; + + // Entity + private final Skeleton _entity; + private final ArmorStand _hologram; + + // Player + private final String _name; + private final UUID _uuid; + private final PlayerInventory _inventory; + + private final int _gems; + + public QuitNPC(Player player, long quitMills) + { + // Managers + _disguise = Managers.get(DisguiseManager.class); + + // Time + _start = System.currentTimeMillis(); + _quitMills = quitMills; + + // Entity + _entity = player.getWorld().spawn(player.getLocation(), Skeleton.class); + _entity.setHealth(player.getHealth()); + _entity.setMaxHealth(player.getMaxHealth()); + _entity.getEquipment().setArmorContents(player.getInventory().getArmorContents()); + UtilEnt.vegetate(_entity, true); + + _hologram = player.getWorld().spawn(player.getLocation(), ArmorStand.class); + _hologram.setCustomNameVisible(true); + _hologram.setVisible(false); + _hologram.setSmall(true); + + _entity.setPassenger(_hologram); + + // Disguise + DisguisePlayer disguise = new DisguisePlayer(_entity, UtilGameProfile.getGameProfile(player)); + _disguise.disguise(disguise); + + // Player + _name = player.getName(); + _uuid = player.getUniqueId(); + _inventory = player.getInventory(); + _gems = Managers.get(EconomyModule.class).Get(player); + + UtilServer.RegisterEvents(this); + } + + public void despawn(boolean pluginRemove) + { + QuitNPCDespawnEvent event = new QuitNPCDespawnEvent(this, pluginRemove); + + UtilServer.CallEvent(event); + + if (event.isCancelled()) + { + return; + } + + _entity.remove(); + _hologram.remove(); + + UtilServer.Unregister(this); + } + + public void dropItems() + { + Location location = _entity.getLocation().add(0, 1, 0); + + for (ItemStack itemStack : _inventory.getContents()) + { + if (itemStack == null || itemStack.getType() == Material.AIR) + { + continue; + } + + location.getWorld().dropItemNaturally(location, itemStack); + } + + for (ItemStack itemStack : _inventory.getArmorContents()) + { + if (itemStack == null || itemStack.getType() == Material.AIR) + { + continue; + } + + location.getWorld().dropItemNaturally(location, itemStack); + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + if (UtilTime.elapsed(_start, _quitMills)) + { + despawn(true); + } + else + { + _hologram.setCustomName("Quitting in " + UtilTime.MakeStr(_start + _quitMills - System.currentTimeMillis())); + } + } + + @EventHandler + public void entityDeath(EntityDeathEvent event) + { + if (!_entity.equals(event.getEntity())) + { + return; + } + + Player killer = event.getEntity().getKiller(); + + if (killer != null) + { + Managers.get(EconomyModule.class).addToStore(killer, "Killing " + F.name(_name + "'s") + " NPC", (int) (_gems * EconomyModule.GEM_KILL_FACTOR)); + } + + event.getDrops().clear(); + _entity.setHealth(_entity.getMaxHealth()); + dropItems(); + despawn(false); + } + + @EventHandler + public void entityCombust(EntityCombustEvent event) + { + if (!_entity.equals(event.getEntity())) + { + return; + } + + event.setCancelled(true); + } + + public String getName() + { + return _name; + } + + public UUID getUniqueId() + { + return _uuid; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPCModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPCModule.java new file mode 100644 index 00000000..2bc11515 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPCModule.java @@ -0,0 +1,131 @@ +package mineplex.gemhunters.death.quitnpc; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; +import org.bukkit.event.player.PlayerQuitEvent; + +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.gemhunters.death.event.QuitNPCDespawnEvent; +import mineplex.gemhunters.death.event.QuitNPCSpawnEvent; +import mineplex.gemhunters.economy.CashOutModule; + +@ReflectivelyCreateMiniPlugin +public class QuitNPCModule extends MiniPlugin +{ + private static final long LOG_OUT_TIME = TimeUnit.SECONDS.toMillis(60); + + private final CashOutModule _cashOut; + + private final Map _npcs; + + private final String _serverName; + private final QuitNPCRepository _repo; + + private QuitNPCModule() + { + super("Quit NPC"); + + _cashOut = require(CashOutModule.class); + + _npcs = new HashMap<>(); + _serverName = UtilServer.getRegion().name() + ":" + UtilServer.getServerName(); + _repo = new QuitNPCRepository(); + } + + public void spawnNpc(Player player) + { + log("Attempting to spawn quit npc for " + player.getName()); + + if (player.getGameMode() != GameMode.SURVIVAL) + { + log(player.getName() + " was not in survival"); + return; + } + + if (_cashOut.isAboutToCashOut(player)) + { + log(player.getName() + " was cashing out"); + return; + } + + // Event + QuitNPCSpawnEvent event = new QuitNPCSpawnEvent(player); + + UtilServer.CallEvent(event); + + if (event.isCancelled()) + { + log("Event cancelled for " + player.getName()); + return; + } + + _npcs.put(player.getUniqueId(), new QuitNPC(player, LOG_OUT_TIME)); + _repo.insertNpc(player.getUniqueId(), _serverName); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + if (UtilPlayer.isSpectator(player)) + { + return; + } + + spawnNpc(player); + } + + @EventHandler + public void npcDespawn(QuitNPCDespawnEvent event) + { + log("Despawning npc for " + _npcs.remove(event.getNpc().getUniqueId()).getName()); + _repo.deleteNpc(event.getNpc().getUniqueId()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onLogin(AsyncPlayerPreLoginEvent event) + { + try + { + String npcServer = _repo.loadNpcServer(event.getUniqueId()).join(); + if (npcServer == null || npcServer.isEmpty()) + { + return; + } + if (npcServer.equals(_serverName)) + { + return; + } + + event.disallow(Result.KICK_OTHER, C.cRed + "You have a combat logger alive on " + npcServer + "! Either wait for it to despawn or join that server directly!"); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public QuitNPC getNPC(Player player) + { + return _npcs.get(player.getUniqueId()); + } + + public boolean hasNPC(Player player) + { + return _npcs.containsKey(player.getUniqueId()); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPCRepository.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPCRepository.java new file mode 100644 index 00000000..160e5352 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/death/quitnpc/QuitNPCRepository.java @@ -0,0 +1,52 @@ +package mineplex.gemhunters.death.quitnpc; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +import mineplex.core.common.util.UtilServer; +import mineplex.serverdata.Region; +import mineplex.serverdata.redis.RedisRepository; +import redis.clients.jedis.Jedis; + +public class QuitNPCRepository extends RedisRepository +{ + private static final String REDIS_KEY_PREFIX = "GemHuntersNPC."; + + public QuitNPCRepository() + { + super(Region.ALL); + } + + public CompletableFuture loadNpcServer(UUID uuid) + { + return CompletableFuture.supplyAsync(() -> + { + try (Jedis jedis = getResource(false)) + { + return jedis.get(getKey(REDIS_KEY_PREFIX + uuid.toString())); + } + }); + } + + public void deleteNpc(UUID uuid) + { + UtilServer.runAsync(() -> + { + try (Jedis jedis = getResource(true)) + { + jedis.del(getKey(REDIS_KEY_PREFIX + uuid.toString())); + } + }); + } + + public void insertNpc(UUID uuid, String serverName) + { + UtilServer.runAsync(() -> + { + try (Jedis jedis = getResource(true)) + { + jedis.setex(getKey(REDIS_KEY_PREFIX + uuid.toString()), 60, serverName); + } + }); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java new file mode 100644 index 00000000..efbf10c3 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java @@ -0,0 +1,335 @@ +package mineplex.gemhunters.economy; + +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +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.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +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.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +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.stats.StatsManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.economy.command.CashOutItemCommand; +import mineplex.gemhunters.economy.command.ResetCooldownCommand; +import mineplex.gemhunters.economy.event.PlayerCashOutCompleteEvent; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; + +@ReflectivelyCreateMiniPlugin +public class CashOutModule extends MiniPlugin +{ + public enum Perm implements Permission + { + CASH_OUT_ITEM_COMMAND, + RESET_COOLDOWN_COMMAND, + } + + private static final DecimalFormat ARMOUR_STAND_FORMAT = new DecimalFormat("0.0"); + public static final ItemStack CASH_OUT_ITEM = new ItemBuilder(Material.EMERALD).setTitle(C.cGreen + "Cash Out").addLore("", "Click to begin the process to cash out.", "Cashing out gives you your gems, shards,", "chests and any particles you have.", "However you will lose all your current loot!").build(); + + private static final int CASH_OUT_SECONDS = 10; + 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 StatsManager _stats; + + private final Map _sessions; + private final Set _aboutToCashOut; + + public CashOutModule() + { + super("Cash Out"); + + _donation = require(DonationManager.class); + _stats = require(StatsManager.class); + + _sessions = new HashMap<>(); + _aboutToCashOut = new HashSet<>(); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.PLAYER.setPermission(Perm.CASH_OUT_ITEM_COMMAND, true, true); + PermissionGroup.DEV.setPermission(Perm.RESET_COOLDOWN_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new CashOutItemCommand(this)); + addCommand(new ResetCooldownCommand(this)); + } + + @EventHandler + public void teleportIn(PlayerTeleportIntoMapEvent event) + { + if (event.isCancelled() || event.getPlayer().getInventory().contains(CASH_OUT_ITEM)) + { + 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 itemSpawn(ItemSpawnEvent event) + { + if (event.getEntity().getItemStack().isSimilar(CASH_OUT_ITEM)) + { + event.setCancelled(true); + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator iterator = _sessions.keySet().iterator(); + + while (iterator.hasNext()) + { + UUID key = iterator.next(); + final 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); + + _aboutToCashOut.add(player.getUniqueId()); + + if (completeEvent.getGems() != EconomyModule.GEM_START_COST) + { + _stats.incrementStat(player, "Gem Hunters.GemsEarned", completeEvent.getGems()); + } + + _donation.rewardCurrencyUntilSuccess(GlobalCurrency.GEM, player, "Earned", completeEvent.getGems()); + + session.endSession(); + iterator.remove(); + + player.getInventory().clear(); + + if (UtilServer.isTestServer()) + { + kickPlayer(player); + } + else + { + Portal.getInstance().sendPlayerToGenericServer(player, GenericServer.HUB, Intent.FORCE_TRANSFER); + + runSyncLater(() -> + { + if (player.isOnline()) + { + kickPlayer(player); + } + }, 50); + } + } + } + } + + @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(priority = EventPriority.MONITOR) + public void entityDamage(EntityDamageEvent event) + { + if (event.isCancelled()) + { + return; + } + + if (!(event.getEntity() instanceof Player)) + { + return; + } + + Player player = (Player) event.getEntity(); + + if (isCashingOut(player)) + { + cancelCashOut(player, "You took damage!"); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void entityAttack(EntityDamageByEntityEvent event) + { + if (event.isCancelled()) + { + return; + } + + if (!(event.getDamager() instanceof Player) || event.getEntity() instanceof ArmorStand) + { + return; + } + + Player player = (Player) event.getDamager(); + + if (isCashingOut(player)) + { + cancelCashOut(player, "You attacked a player!"); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void playerQuit(PlayerQuitEvent event) + { + _aboutToCashOut.remove(event.getPlayer().getUniqueId()); + } + + 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; + } + + _sessions.put(key, new CashOutSession(player, CASH_OUT_SECONDS)); + } + + 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 boolean isAboutToCashOut(Player player) + { + return _aboutToCashOut.contains(player.getUniqueId()); + } + + public CashOutSession getCashOutSession(Player player) + { + for (UUID key : _sessions.keySet()) + { + if (key.equals(player.getUniqueId())) + { + return _sessions.get(key); + } + } + + return null; + } + + private void kickPlayer(Player player) + { + player.kickPlayer(C.cGreen + "Imagine you are being sent to the lobby."); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutSession.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutSession.java new file mode 100644 index 00000000..b996183b --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutSession.java @@ -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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java new file mode 100644 index 00000000..b908558c --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java @@ -0,0 +1,158 @@ +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.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.donation.DonationManager; +import mineplex.core.donation.Donor; +import mineplex.gemhunters.economy.command.GiveGemsCommand; +import mineplex.gemhunters.economy.event.PlayerCashOutCompleteEvent; +import mineplex.gemhunters.economy.event.PlayerEarnGemsEvent; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; + +@ReflectivelyCreateMiniPlugin +public class EconomyModule extends MiniClientPlugin +{ + public enum Perm implements Permission + { + GIVE_GEMS_COMMAND, + } + + public static final float GEM_KILL_FACTOR = 0.5F; + public static final int GEM_START_COST = 100; + + private final DonationManager _donation; + + private Player _mostValuable; + private int _mostGems; + + public EconomyModule() + { + super("Economy"); + + _donation = require(DonationManager.class); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.GIVE_GEMS_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new GiveGemsCommand(this)); + } + + @EventHandler + public void teleportIn(PlayerTeleportIntoMapEvent event) + { + Player player = event.getPlayer(); + addToStore(event.getPlayer(), null, GEM_START_COST); + + 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 != null) + { + Player killerPlayer = (Player) killer; + // Don't award the player negative gems, in the case of an overflow + int newGems = Math.min((int) (oldGems * GEM_KILL_FACTOR), 0); + + 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) + { + PlayerEarnGemsEvent event = new PlayerEarnGemsEvent(player, gems, reason); + UtilServer.CallEvent(event); + + if (event.isCancelled() || event.getGems() == 0) + { + return; + } + + gems = event.getGems(); + reason = event.getReason(); + + 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 void setStore(Player player, int gems) + { + Set(player, gems); + } + + public int getGems(Player player) + { + return Get(player); + } + + @Override + protected void Set(Player player, Integer data) + { + super.Set(player, data); + + if (_mostValuable == null || _mostGems < data) + { + _mostValuable = player; + _mostGems = data; + } + } + + public Player getMostValuablePlayer() + { + return _mostValuable; + } + + @Override + protected Integer addPlayer(UUID uuid) + { + return 0; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/CashOutItemCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/CashOutItemCommand.java new file mode 100644 index 00000000..ac11be52 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/CashOutItemCommand.java @@ -0,0 +1,27 @@ +package mineplex.gemhunters.economy.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.gemhunters.economy.CashOutModule; + +public class CashOutItemCommand extends CommandBase +{ + public CashOutItemCommand(CashOutModule plugin) + { + super(plugin, CashOutModule.Perm.CASH_OUT_ITEM_COMMAND, "cashout", "ct", "cashitem", "cashoutitem"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (caller.getInventory().contains(CashOutModule.CASH_OUT_ITEM)) + { + return; + } + + caller.sendMessage(F.main(Plugin.getName(), "Giving you a new cash out item.")); + caller.getInventory().addItem(CashOutModule.CASH_OUT_ITEM); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/GiveGemsCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/GiveGemsCommand.java new file mode 100644 index 00000000..8dba4e6f --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/GiveGemsCommand.java @@ -0,0 +1,45 @@ +package mineplex.gemhunters.economy.command; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.gemhunters.economy.EconomyModule; + +public class GiveGemsCommand extends CommandBase +{ + public GiveGemsCommand(EconomyModule plugin) + { + super(plugin, EconomyModule.Perm.GIVE_GEMS_COMMAND, "givegems"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 2) + { + caller.sendMessage(F.help("/" + _aliasUsed + " ", "Adds an amount of gems to a player's gems earned.", ChatColor.DARK_RED)); + 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.")); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/ResetCooldownCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/ResetCooldownCommand.java new file mode 100644 index 00000000..004deb33 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/command/ResetCooldownCommand.java @@ -0,0 +1,21 @@ +package mineplex.gemhunters.economy.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.recharge.Recharge; +import mineplex.gemhunters.economy.CashOutModule; + +public class ResetCooldownCommand extends CommandBase +{ + public ResetCooldownCommand(CashOutModule plugin) + { + super(plugin, CashOutModule.Perm.RESET_COOLDOWN_COMMAND, "resetcashout"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Recharge.Instance.useForce(caller, "Cash Out", 0); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/event/PlayerCashOutCompleteEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/event/PlayerCashOutCompleteEvent.java new file mode 100644 index 00000000..16462944 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/event/PlayerCashOutCompleteEvent.java @@ -0,0 +1,44 @@ +package mineplex.gemhunters.economy.event; + +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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/event/PlayerEarnGemsEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/event/PlayerEarnGemsEvent.java new file mode 100644 index 00000000..ae73ce69 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/event/PlayerEarnGemsEvent.java @@ -0,0 +1,72 @@ +package mineplex.gemhunters.economy.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class PlayerEarnGemsEvent extends PlayerEvent implements Cancellable +{ + + private static final HandlerList HANDLERS = new HandlerList(); + + private int _gems; + private String _reason; + private boolean _cancel; + + public PlayerEarnGemsEvent(Player player, int gems, String reason) + { + super(player); + + _gems = gems; + _reason = reason; + } + + public void incrementGems(int gems) + { + _gems += gems; + } + + public void setGems(int gems) + { + _gems = gems; + } + + public int getGems() + { + return _gems; + } + + public void setReason(String reason) + { + _reason = reason; + } + + public String getReason() + { + return _reason; + } + + 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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/join/JoinModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/join/JoinModule.java new file mode 100644 index 00000000..43527851 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/join/JoinModule.java @@ -0,0 +1,127 @@ +package mineplex.gemhunters.join; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.UtilItem; +import mineplex.core.recharge.Recharge; +import mineplex.gemhunters.death.quitnpc.QuitNPC; +import mineplex.gemhunters.death.quitnpc.QuitNPCModule; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.loot.InventoryModule; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.persistence.PersistenceData; +import mineplex.gemhunters.persistence.PersistenceModule; +import mineplex.gemhunters.persistence.PersistenceRepository; +import mineplex.gemhunters.quest.QuestModule; +import mineplex.gemhunters.spawn.SpawnModule; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +@ReflectivelyCreateMiniPlugin +public class JoinModule extends MiniPlugin +{ + + private static final double MAXIMUM_DURABILITY_LOSS = 0.85; + private final CoreClientManager _client; + private final EconomyModule _economy; + private final LootModule _loot; + private final QuestModule _quest; + private final PersistenceModule _persistence; + private final QuitNPCModule _npc; + private final InventoryModule _inventory; + private final SpawnModule _spawn; + + private JoinModule() + { + super("Join"); + + _client = require(CoreClientManager.class); + _economy = require(EconomyModule.class); + _loot = require(LootModule.class); + _quest = require(QuestModule.class); + _persistence = require(PersistenceModule.class); + _npc = require(QuitNPCModule.class); + _inventory = require(InventoryModule.class); + _spawn = require(SpawnModule.class); + } + + @EventHandler + public void playerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + CoreClient client = _client.Get(player); + PersistenceRepository repository = _persistence.getRepository(); + Consumer response = data -> + runSync(() -> { + _economy.setStore(player, data.getGems()); + _quest.setPlayerData(player, data.getQuestData()); + player.teleport(data.getLocation()); + player.setHealth(data.getHealth()); + player.setMaxHealth(data.getMaxHealth()); + player.setFoodLevel(data.getHunger()); + loseDurability(data.getItems(), data.getSaveTime()); + for (ItemStack itemStack : data.getItems()) + { + _loot.handleRewardItem(player, itemStack); + } + player.getInventory().addItem(data.getItems()); + loseDurability(data.getArmour(), data.getSaveTime()); + player.getInventory().setArmorContents(data.getArmour()); + _inventory.unlockSlots(player, data.getSlots(), false); + Recharge.Instance.useForce(player, "Cash Out", data.getCashOutTime()); + }); + + player.getInventory().clear(); + + if (_npc.hasNPC(player)) + { + QuitNPC npc = _npc.getNPC(player); + npc.despawn(true); + } + + _inventory.resetSlots(player); + _spawn.teleportToSpawn(player); + + runAsync(() -> + { + repository.getPersistenceData(response, client); + + if (!repository.exists(client)) + { + runSync(() -> _spawn.teleportToSpawn(player)); + } + }, 40); + } + + private void loseDurability(ItemStack[] items, long time) + { + long diff = System.currentTimeMillis() - time; + long hours = TimeUnit.MILLISECONDS.toHours(diff); + + for (ItemStack item : items) + { + if (!UtilItem.isSword(item) && !UtilItem.isArmor(item)) + { + continue; + } + + short max = item.getType().getMaxDurability(); + short change = (short) (((double) max / 100D) * hours); + short apply = (short) (item.getDurability() + change); + + if (apply > max * MAXIMUM_DURABILITY_LOSS) + { + apply = (short) (max * MAXIMUM_DURABILITY_LOSS); + } + + item.setDurability(apply); + } + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/ChestProperties.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/ChestProperties.java new file mode 100644 index 00000000..fe2ff3aa --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/ChestProperties.java @@ -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 _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 getSpawnIndexes() + { + return _spawnedIndexes; + } + + public void setLastSpawn() + { + _lastSpawn = System.currentTimeMillis(); + } + + public long getLastSpawn() + { + return _lastSpawn; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java new file mode 100644 index 00000000..92c349c1 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java @@ -0,0 +1,149 @@ +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.PlayerJoinEvent; +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 _slotsUnlocked; + + private InventoryModule() + { + super("Unlocker"); + + _loot = require(LootModule.class); + + _slotsUnlocked = new HashMap<>(); + } + + @EventHandler + public void respawn(PlayerCustomRespawnEvent event) + { + resetSlots(event.getPlayer()); + } + + @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) + { + unlockSlots(player, slots, true); + } + + public void unlockSlots(Player player, int slots, boolean inform) + { + _slotsUnlocked.putIfAbsent(player.getUniqueId(), 0); + + 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; + + for (int i = start; i < end; i++) + { + inv.setItem(i, null); + } + + if (inform) + { + 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); + } + + public void resetSlots(Player player) + { + Inventory inv = player.getInventory(); + + _slotsUnlocked.put(player.getUniqueId(), 0); + + for (int i = START_INDEX; i < inv.getSize(); i++) + { + inv.setItem(i, LOCKED); + } + } + + public int getSlots(Player player) + { + return _slotsUnlocked.get(player.getUniqueId()); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootItem.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootItem.java new file mode 100644 index 00000000..74420cb7 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootItem.java @@ -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}.
+ * 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 skill or ability attached to it which + * you can use in code. + * + * @return + */ + public String getMetadata() + { + return _metadata; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java new file mode 100644 index 00000000..c5296030 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java @@ -0,0 +1,741 @@ +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 mineplex.core.common.util.F; +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.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +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.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +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.stats.StatsManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.economy.event.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.world.WorldDataModule; + +@ReflectivelyCreateMiniPlugin +public class LootModule extends MiniPlugin +{ + public enum Perm implements Permission + { + SPAWN_CHEST_COMMAND, + UPDATE_LOOT_COMMAND, + } + + 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 StatsManager _stats; + private final WorldDataModule _worldData; + + private final Map> _chestLoot; + private final Map _chestProperties; + private final Set _spawnedChest; + private final Set _itemRewards; + private final Set _shownPlayers; + + private LootModule() + { + super("Loot"); + + _economy = require(EconomyModule.class); + _sheets = require(GoogleSheetsManager.class); + _safezone = require(SafezoneModule.class); + _stats = require(StatsManager.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); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.ADMIN.setPermission(Perm.SPAWN_CHEST_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.UPDATE_LOOT_COMMAND, true, true); + } + + @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 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>> map = _sheets.getSheetData(SHEET_FILE_NAME); + + for (String key : map.keySet()) + { + if (key.equals(CHEST_MASTER_SHEET_NAME)) + { + int row = 0; + + for (List rows : map.get(key)) + { + row++; + try + { + ChestProperties properties = CHEST_DESERIALISER.deserialise(rows.toArray(new String[0])); + _chestProperties.put(properties.getDataKey(), properties); + } + catch (Exception e) + { + } + } + + continue; + } + + Set items = new HashSet<>(); + int row = 0; + + for (List rows : map.get(key)) + { + row++; + try + { + items.add(DESERIALISER.deserialise(rows.toArray(new String[0]))); + } + catch (Exception e) + { + } + } + + _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 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 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++; + } + + //Bukkit.broadcastMessage("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max + " and suitable=" + suitable); + + if (!suitable) + { + return; + } + + _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 used = new HashSet<>(); + Set 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 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 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 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; + } + + _stats.incrementStat(player, "Gem Hunters.ChestsOpened", 1); + 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(priority = EventPriority.HIGH) + public void pickupItem(PlayerPickupItemEvent event) + { + if (event.getItem() == null || event.isCancelled()) + { + return; + } + + handleRewardItem(event.getPlayer(), event.getItem().getItemStack()); + } + + @EventHandler + public void dropItem(PlayerDropItemEvent event) + { + if (event.getItemDrop() == null || event.isCancelled()) + { + return; + } + + if (!_safezone.isInSafeZone(event.getPlayer())) + { + return; + } + + ItemStack dropped = event.getItemDrop().getItemStack(); + + for (LootItemReward storedReward : _itemRewards) + { + if (storedReward.getItemStack().isSimilar(dropped)) + { + event.setCancelled(true); + event.getItemDrop().remove(); + event.getPlayer().sendMessage(F.main(_moduleName, "You can't drop special items in Safezones.")); + return; + } + } + } + + public void handleRewardItem(Player player, ItemStack itemStack) + { + LootItem lootItem = fromItemStack(itemStack); + LootItemReward reward = null; + + for (LootItemReward storedReward : _itemRewards) + { + if (storedReward.getItemStack().isSimilar(itemStack)) + { + reward = storedReward; + } + } + + if (reward == null && lootItem != null && lootItem.getMetadata() != null) + { + String[] metadataSplit = lootItem.getMetadata().split(" "); + String key = metadataSplit[0]; + String[] values = new String[metadataSplit.length - 1]; + + System.arraycopy(metadataSplit, 1, values, 0, metadataSplit.length - 1); + + 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); + } + + if (reward != null) + { + reward.collectItem(player); + } + } + + public void addItemReward(LootItemReward reward) + { + _itemRewards.add(reward); + } + + @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() == null) + { + continue; + } + + 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 iterator = _itemRewards.iterator(); + + while (iterator.hasNext()) + { + LootItemReward reward = iterator.next(); + + if (reward.getPlayer() != null && player.equals(reward.getPlayer())) + { + reward.success(); + iterator.remove(); + + for (Entity entity : reward.getPlayer().getWorld().getEntities()) + { + if (entity instanceof Item) + { + Item item = (Item) entity; + + if (item.getItemStack().getType() == reward.getItemStack().getType()) + { + entity.remove(); + } + } + } + } + } + } + + @EventHandler + public void playerDeath(PlayerDeathEvent event) + { + for (LootItemReward reward : _itemRewards) + { + if (reward.getPlayer() == null) + { + continue; + } + if (reward.getPlayer().equals(event.getEntity())) + { + reward.death(event); + } + } + } + + public final Set getShownPlayers() + { + return _shownPlayers; + } + + public final Set getChestItems(String key) + { + return _chestLoot.get(key); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/SpawnedChest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/SpawnedChest.java new file mode 100644 index 00000000..f0a8ae9d --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/SpawnedChest.java @@ -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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/command/SpawnChestCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/command/SpawnChestCommand.java new file mode 100644 index 00000000..0c795711 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/command/SpawnChestCommand.java @@ -0,0 +1,45 @@ +package mineplex.gemhunters.loot.command; + +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.gemhunters.loot.LootModule; + +public class SpawnChestCommand extends CommandBase +{ + public SpawnChestCommand(LootModule plugin) + { + super(plugin, LootModule.Perm.SPAWN_CHEST_COMMAND, "spawnchest"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0) + { + caller.sendMessage(F.help("/" + _aliasUsed + " ", "Spawns a chest at your location.", ChatColor.DARK_RED)); + 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); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/command/UpdateLootCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/command/UpdateLootCommand.java new file mode 100644 index 00000000..ae6ae4b1 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/command/UpdateLootCommand.java @@ -0,0 +1,30 @@ +package mineplex.gemhunters.loot.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +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 +{ + public UpdateLootCommand(LootModule plugin) + { + super(plugin, LootModule.Perm.UPDATE_LOOT_COMMAND, "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.")); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/deserialisers/ChestPropertiesDeserialiser.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/deserialisers/ChestPropertiesDeserialiser.java new file mode 100644 index 00000000..15898b8f --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/deserialisers/ChestPropertiesDeserialiser.java @@ -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 +{ + + @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); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/deserialisers/LootItemDeserialiser.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/deserialisers/LootItemDeserialiser.java new file mode 100644 index 00000000..61fc7660 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/deserialisers/LootItemDeserialiser.java @@ -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.
+ *
+ * Arguments should follow the form:
+ *

    + *
  • Material
  • + *
  • Material Data
  • + *
  • Max Durability
  • + *
  • Amount
  • + *
  • Item Name (optional)
  • + *
  • Item Lore (optional) each line separated by colons
  • + *
  • Enchantments (optional) Has a NAME:LEVEL format with multiple + * enchantments being separated by commas
  • + *
  • Probability
  • + *
  • Metadata (optional)
  • + *
+ * Thus derserialise is guaranteed to have at least 8 strings passed in.
+ * 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 +{ + + @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); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/event/PlayerChestOpenEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/event/PlayerChestOpenEvent.java new file mode 100644 index 00000000..fb7d4058 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/event/PlayerChestOpenEvent.java @@ -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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java new file mode 100644 index 00000000..323c184f --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootChestReward.java @@ -0,0 +1,45 @@ +package mineplex.gemhunters.loot.rewards; + +import mineplex.gemhunters.util.SlackRewardBot; +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(success -> SlackRewardBot.logReward(_player, this, success ? "Success" : "Failure"), _player, _chestName + " Chest", _amount); + } + + @Override + public void onDeath() + { + + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java new file mode 100644 index 00000000..8956f8a3 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootGadgetReward.java @@ -0,0 +1,54 @@ +package mineplex.gemhunters.loot.rewards; + +import mineplex.core.server.util.TransactionResponse; +import mineplex.gemhunters.util.SlackRewardBot; +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)) + { + _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", (int) (500 + 1000 * Math.random()), success -> SlackRewardBot.logReward(_player, this, (success ? "Success" : "Failure") + " (Shard Dupe)")); + } + else + { + _donation.purchaseUnknownSalesPackage(_player, _gadget, GlobalCurrency.TREASURE_SHARD, 0, true, transaction -> SlackRewardBot.logReward(_player, this, transaction == TransactionResponse.Success ? "Success" : "Failure")); + } + } + + @Override + public void onDeath() + { + + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootItemReward.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootItemReward.java new file mode 100644 index 00000000..49acb385 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootItemReward.java @@ -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 != null && 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() + { + onSuccessful(); + } + + public final void death(PlayerDeathEvent event) + { + _player = null; + } + + public boolean isFirstPickup() + { + return _firstItemPickup == 0; + } + + public Player getPlayer() + { + return _player; + } + + public ItemStack getItemStack() + { + return _itemStack; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java new file mode 100644 index 00000000..d1c2dacd --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootRankReward.java @@ -0,0 +1,82 @@ +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.account.permissions.PermissionGroup; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.F; +import mineplex.core.donation.DonationManager; +import mineplex.gemhunters.util.SlackRewardBot; + +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); + PermissionGroup group = client.getPrimaryGroup(); + PermissionGroup newGroup = 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 (group) + { + case PLAYER: + newGroup = PermissionGroup.ULTRA; + break; + case ULTRA: + newGroup = PermissionGroup.HERO; + break; + case HERO: + newGroup = PermissionGroup.LEGEND; + break; + case LEGEND: + newGroup = PermissionGroup.TITAN; + break; + case TITAN: + newGroup = PermissionGroup.ETERNAL; + break; + default: + break; + } + + // A suitable rank could not be found. + if (newGroup == null) + { + _player.sendMessage(F.main("Loot", "You already have eternal ( You are lucky :) ). So instead you can have " + CONSOLATION_PRICE + " shards.")); + _donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", CONSOLATION_PRICE, success -> SlackRewardBot.logReward(_player, this, (success ? "Success" : "Failure") + " (Shard Dupe)")); + return; + } + + final String status = newGroup.name(); + + _clientManager.setPrimaryGroup(_player, newGroup, () -> SlackRewardBot.logReward(_player, this, status)); + } + + @Override + public void onDeath() {} +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java new file mode 100644 index 00000000..458e577e --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/rewards/LootShardReward.java @@ -0,0 +1,43 @@ +package mineplex.gemhunters.loot.rewards; + +import mineplex.gemhunters.util.SlackRewardBot; +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, success -> SlackRewardBot.logReward(_player, this, success ? "Success" : "Failure")); + } + + @Override + public void onDeath() + { + + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java new file mode 100644 index 00000000..0f58d3a4 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java @@ -0,0 +1,982 @@ +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 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; + +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.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +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.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +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 mineplex.gemhunters.map.command.MapCommand; + +/** + * All item map code was adapted from Clans.
+ */ +@ReflectivelyCreateMiniPlugin +public class ItemMapModule extends MiniPlugin +{ + public enum Perm implements Permission + { + MAP_COMMAND, + } + + // 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> _comparator; + private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][]; + private HashMap _map = new HashMap(); + private short _mapId = -1; + private HashMap _mapInfo = new HashMap(); + private HashMap _scale = new HashMap(); + // Use LinkedList because operations are either add(Entry) which is O(1) and remove(0) which is O(1) on LinkedList but O(n) on ArrayList + private LinkedList> _scanList = new LinkedList>(); + private World _world; + private WorldServer _nmsWorld; + private ChunkProviderServer _chunkProviderServer; + private ChunkRegionLoader _chunkRegionLoader; + + private ItemMapModule() + { + super("Map"); + + _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 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(); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.PLAYER.setPermission(Perm.MAP_COMMAND, true, true); + } + + private void initialScan() + { + System.out.println("Beginning initial scan. There are " + _scanList.size() + " regions to scan"); + + // How many regions before logging an update (Currently set to every 20%) + int logPer = _scanList.size() / 5; + + while (!_scanList.isEmpty()) + { + Entry entry = _scanList.remove(0); + if (_scanList.size() % logPer == 0) + { + System.out.println("Running initial render... " + _scanList.size() + " sections to go"); + } + + int startingX = entry.getKey(); + int startingZ = entry.getValue(); + + boolean outsideMap = startingZ < -HALF_WORLD_SIZE; + + scanWorldMap(startingX, startingZ, !outsideMap, true); + + if (outsideMap) + { + continue; + } + + for (int scale = 1; scale < _scale.size(); scale++) + { + if (scale == 3) + continue; + + drawWorldScale(scale, startingX, startingZ); + colorWorldHeight(scale, startingX, startingZ); + } + + colorWorldHeight(0, startingX, startingZ); + } + + for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL) + { + for (int z = -HALF_WORLD_SIZE; z < HALF_WORLD_SIZE; z += BLOCK_SCAN_INTERVAL) + { + drawWorldScale(3, x, z); + colorWorldHeight(3, x, z); + } + } + + System.out.println("Finished first map scan and render"); + } + + private void setupRenderer(MapView view) + { + 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 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 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(priority = EventPriority.HIGHEST) + public void playerJoin(PlayerJoinEvent event) + { + handleGive(event.getPlayer()); + } + + @EventHandler + public void respawn(PlayerCustomRespawnEvent event) + { + handleGive(event.getPlayer()); + } + + public void handleGive(Player player) + { + MapInfo info = new MapInfo(_mapId); + 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 onQuit(PlayerQuitEvent event) + { + _mapInfo.remove(event.getPlayer().getName()); + } + + 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 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 _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; + } + + @Override + public void addCommands() + { + addCommand(new MapCommand(this)); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapRenderer.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapRenderer.java new file mode 100644 index 00000000..d191cf23 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapRenderer.java @@ -0,0 +1,295 @@ +package mineplex.gemhunters.map; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilTime; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.gemhunters.economy.EconomyModule; +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; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.map.*; + +import java.awt.*; +import java.util.Set; +import java.util.UUID; + +/** + * All item map code was adapted from Clans.
+ */ +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 EconomyModule _economy; + 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); + _economy = Managers.require(EconomyModule.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() || event.getEventLocations() == null) + { + continue; + } + + for (Location point : event.getEventLocations()) + { + 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, (byte) (rotation & 0xF), 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 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; + } + else if (other.equals(_economy.getMostValuablePlayer())) + { + cursorDisplay = MapCursor.Type.RED_POINTER; + } + + if (cursorDisplay == null) + { + continue; + } + + byte b0 = (byte) (int) Math.min(127, (mapX * 2.0F) + 0.5D); + byte b1 = (byte) (int) Math.max(-127, (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); + } + } + } + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/MapInfo.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/MapInfo.java new file mode 100644 index 00000000..5af724e5 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/MapInfo.java @@ -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 _lastZooms = new ArrayList(); + 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 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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/command/MapCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/command/MapCommand.java new file mode 100644 index 00000000..d529a7a9 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/map/command/MapCommand.java @@ -0,0 +1,22 @@ +package mineplex.gemhunters.map.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.gemhunters.map.ItemMapModule; + +public class MapCommand extends CommandBase +{ + public MapCommand(ItemMapModule plugin) + { + super(plugin, ItemMapModule.Perm.MAP_COMMAND, "map", "getmap"); + } + + @Override + public void Execute(Player caller, String[] args) + { + caller.sendMessage(F.main(Plugin.getName(), "Giving you a new map.")); + Plugin.setMap(caller); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/moderation/ModerationModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/moderation/ModerationModule.java new file mode 100644 index 00000000..9afe397c --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/moderation/ModerationModule.java @@ -0,0 +1,164 @@ +package mineplex.gemhunters.moderation; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.GameMode; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.incognito.IncognitoManager; +import mineplex.core.incognito.events.IncognitoStatusChangeEvent; +import mineplex.core.teleport.event.MineplexTeleportEvent; +import mineplex.gemhunters.moderation.command.ModeratorModeCommand; +import mineplex.gemhunters.spawn.SpawnModule; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; + +@ReflectivelyCreateMiniPlugin +public class ModerationModule extends MiniPlugin +{ + public enum Perm implements Permission + { + MODERATOR_MODE_COMMAND, + MODERATOR_MODE_BYPASS, + AUTO_OP, + } + + private final CoreClientManager _client; + private final IncognitoManager _incognito; + private final SpawnModule _spawn; + + private final Set _moderators; + + private ModerationModule() + { + super("Moderation"); + + _client = require(CoreClientManager.class); + _incognito = require(IncognitoManager.class); + _spawn = require(SpawnModule.class); + + _moderators = new HashSet<>(); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.TRAINEE.setPermission(Perm.MODERATOR_MODE_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.MODERATOR_MODE_BYPASS, true, true); + PermissionGroup.ADMIN.setPermission(Perm.AUTO_OP, true, true); + if (UtilServer.isTestServer()) + { + PermissionGroup.QAM.setPermission(Perm.AUTO_OP, false, true); + } + } + + @Override + public void addCommands() + { + addCommand(new ModeratorModeCommand(this)); + } + + @EventHandler + public void teleport(MineplexTeleportEvent event) + { + Player player = event.getPlayer(); + + if (isModerating(player) || isBypassing(player)) + { + return; + } + + enableModeratorMode(player); + } + + @EventHandler + public void vanish(IncognitoStatusChangeEvent event) + { + Player player = event.getPlayer(); + + if (isBypassing(player)) + { + return; + } + + if (isModerating(player) && !event.getNewState()) + { + disableModeratorMode(player); + } + else if (event.getNewState()) + { + enableModeratorMode(player); + } + } + + @EventHandler + public void mapTeleport(PlayerTeleportIntoMapEvent event) + { + Player player = event.getPlayer(); + + if (isBypassing(player) || !_incognito.Get(player).Status) + { + return; + } + + enableModeratorMode(player); + } + + @EventHandler + public void autoOp(PlayerJoinEvent event) + { + if (_client.Get(event.getPlayer()).hasPermission(Perm.AUTO_OP)) + { + event.getPlayer().setOp(true); + } else + { + event.getPlayer().setOp(false); + } + } + + public void enableModeratorMode(Player player) + { + player.sendMessage(F.main(_moduleName, "Enabled moderator mode.")); + player.setGameMode(GameMode.SPECTATOR); + player.getInventory().clear(); + + ((CraftPlayer) player).getHandle().spectating = true; + + _moderators.add(player.getUniqueId()); + } + + public void disableModeratorMode(Player player) + { + player.sendMessage(F.main(_moduleName, "Disabled moderator mode.")); + player.setGameMode(GameMode.SURVIVAL); + + ((CraftPlayer) player).getHandle().spectating = false; + + _spawn.teleportToSpawn(player); + + _moderators.remove(player.getUniqueId()); + } + + public boolean isModerating(Player player) + { + return _moderators.contains(player.getUniqueId()); + } + + public boolean isBypassing(Player player) + { + return _client.Get(player).hasPermission(Perm.MODERATOR_MODE_BYPASS); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/moderation/command/ModeratorModeCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/moderation/command/ModeratorModeCommand.java new file mode 100644 index 00000000..668651b9 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/moderation/command/ModeratorModeCommand.java @@ -0,0 +1,27 @@ +package mineplex.gemhunters.moderation.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.gemhunters.moderation.ModerationModule; + +public class ModeratorModeCommand extends CommandBase +{ + public ModeratorModeCommand(ModerationModule plugin) + { + super(plugin, ModerationModule.Perm.MODERATOR_MODE_COMMAND, "modmode", "staffmode", "mm", "o"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (Plugin.isModerating(caller)) + { + Plugin.disableModeratorMode(caller); + } + else + { + Plugin.enableModeratorMode(caller); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/MountData.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/MountData.java new file mode 100644 index 00000000..eed69426 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/MountData.java @@ -0,0 +1,51 @@ +package mineplex.gemhunters.mount; + +import org.bukkit.entity.Horse; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class MountData +{ + + private final Player _player; + private Horse _entity; + private long _cooldown; + private ItemStack _item; + + MountData(Player player) + { + _player = player; + } + + public Player getPlayer() + { + return _player; + } + + public void onSpawn(Horse entity, long cooldown, ItemStack item) + { + _entity = entity; + _cooldown = cooldown; + _item = item; + } + + public void onRemove() + { + _entity = null; + } + + public Horse getEntity() + { + return _entity; + } + + public long getCooldown() + { + return _cooldown; + } + + public ItemStack getItem() + { + return _item; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/MountModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/MountModule.java new file mode 100644 index 00000000..022d5dd0 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/MountModule.java @@ -0,0 +1,403 @@ +package mineplex.gemhunters.mount; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Horse.Color; +import org.bukkit.entity.Horse.Style; +import org.bukkit.entity.Horse.Variant; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.HorseInventory; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.MiniClientPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.cosmetic.CosmeticManager; +import mineplex.core.disguise.DisguiseManager; +import mineplex.core.disguise.disguises.DisguiseBase; +import mineplex.core.disguise.disguises.DisguiseInsentient; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.event.GadgetEnableEvent; +import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.GemHuntersMountGadget; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.game.GameDisplay; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.utils.UtilVariant; +import mineplex.gemhunters.loot.LootItem; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.mount.command.MountSkinsCommand; +import mineplex.gemhunters.mount.command.SpawnMountCommand; + +@ReflectivelyCreateMiniPlugin +public class MountModule extends MiniClientPlugin +{ + + public enum Perm implements Permission + { + + MOUNT_SKINS_COMMAND, + SPAWN_MOUNT_COMMAND + } + + private static final ItemStack SADDLE = new ItemStack(Material.SADDLE); + private static final int HEALTH = 40; + private static final int MAX_DIST = 25 * 25; + private static final int MIN_DIST = 4 * 4; + + private final CosmeticManager _cosmetic; + private final DisguiseManager _disguise; + private final LootModule _loot; + private final GadgetManager _gadget; + + private MountModule() + { + super("Mount"); + + _cosmetic = require(CosmeticManager.class); + _disguise = require(DisguiseManager.class); + _loot = require(LootModule.class); + _gadget = require(GadgetManager.class); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.PLAYER.setPermission(Perm.MOUNT_SKINS_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.SPAWN_MOUNT_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new MountSkinsCommand(this)); + addCommand(new SpawnMountCommand(this)); + } + + @Override + protected MountData addPlayer(UUID uuid) + { + return null; + } + + @EventHandler + public void playerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + + Set(player, new MountData(player)); + } + + @EventHandler + public void playerInteract(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + LootItem lootItem = _loot.fromItemStack(player.getItemInHand()); + + if (lootItem == null || lootItem.getMetadata() == null) + { + return; + } + + String metadata = lootItem.getMetadata(); + String[] split = metadata.split(" "); + + if (split.length < 2 || !split[0].equals("MOUNT")) + { + return; + } + + String cooldownString = split[1]; + long cooldown; + + try + { + cooldown = TimeUnit.MINUTES.toMillis(Integer.parseInt(cooldownString)); + } + catch (IllegalArgumentException e) + { + return; + } + + if (!Recharge.Instance.usable(player, getName(), true) || !Recharge.Instance.use(player, "Mount Interact", 250, false, false)) + { + return; + } + + MountData data = Get(player); + + if (data.getEntity() != null) + { + player.sendMessage(F.main(_moduleName, "You already have an active mount.")); + return; + } + + spawnHorse(player, data, lootItem.getItemStack(), cooldown); + } + + public void spawnHorse(Player player, MountData data, ItemStack itemStack, long cooldown) + { + Location location = player.getLocation().add(0, 1, 0); + GemHuntersMountGadget gadget = (GemHuntersMountGadget) _gadget.getGameCosmeticManager().getActiveCosmetic( + player, + GameDisplay.GemHunters, + "Mount Skins" + ); + + Horse horse; + + if (gadget == null) + { + horse = UtilVariant.spawnHorse(location, Variant.HORSE); + horse.setColor(Color.BROWN); + horse.setStyle(Style.NONE); + } + else + { + horse = gadget.getType().spawn(location, _disguise); + } + + String name = player.getName(); + horse.setCustomName(name + "'" + (name.charAt(name.length() - 1) == 's' ? "" : "s") + " Mount"); + horse.setCustomNameVisible(true); + horse.setJumpStrength(1); + horse.getInventory().setSaddle(SADDLE); + horse.getInventory().setArmor(new ItemStack(itemStack.getType())); + horse.setDomestication(1); + horse.setMaxDomestication(1); + horse.setOwner(player); + horse.setTamed(true); + horse.setCarryingChest(true); + horse.setMaxHealth(HEALTH); + horse.setHealth(HEALTH); + UtilEnt.vegetate(horse); + + DisguiseBase disguise = _disguise.getActiveDisguise(horse); + + if (disguise != null && disguise instanceof DisguiseInsentient) + { + ((DisguiseInsentient) disguise).setName(name); + } + + data.onSpawn(horse, cooldown, itemStack); + player.sendMessage(F.main(_moduleName, "You spawned your " + F.name(getName()) + ".")); + } + + @EventHandler + public void horseDeath(EntityDeathEvent event) + { + if (!(event.getEntity() instanceof Horse)) + { + return; + } + + Horse horse = (Horse) event.getEntity(); + + for (MountData data : GetValues()) + { + if (data.getEntity() == null || !horse.equals(data.getEntity())) + { + continue; + } + + event.getDrops().clear(); + event.setDroppedExp(0); + Recharge.Instance.use(data.getPlayer(), getName(), data.getCooldown(), true, true); + Recharge.Instance.Get(data.getPlayer()).get(getName()).Item = data.getItem(); + return; + } + } + + @EventHandler + public void playerDeath(PlayerDeathEvent event) + { + Player player = event.getEntity(); + + for (MountData data : GetValues()) + { + if (!player.equals(data.getPlayer()) || data.getEntity() == null) + { + continue; + } + + data.getEntity().remove(); + return; + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + for (MountData data : GetValues()) + { + if (!player.equals(data.getPlayer()) || data.getEntity() == null) + { + continue; + } + + data.getEntity().remove(); + return; + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + for (MountData data : GetValues()) + { + Player player = data.getPlayer(); + Horse horse = data.getEntity(); + + if (horse == null) + { + continue; + } + else if (horse.isDead() || !horse.isValid()) + { + data.onRemove(); + } + + double offset = UtilMath.offsetSquared(player, horse); + + if (offset > MAX_DIST) + { + horse.teleport(player); + } + else if (offset > MIN_DIST) + { + UtilEnt.CreatureMove(horse, player.getLocation(), 2); + } + } + } + + @EventHandler + public void horseInteract(PlayerInteractEntityEvent event) + { + if (!(event.getRightClicked() instanceof Horse)) + { + return; + } + + Player player = event.getPlayer(); + Horse horse = (Horse) event.getRightClicked(); + + for (MountData data : GetValues()) + { + if (player.equals(data.getPlayer()) || !horse.equals(data.getEntity())) + { + continue; + } + + player.sendMessage(F.main(_moduleName, "This is not your mount.")); + event.setCancelled(true); + return; + } + } + + @EventHandler + public void horseDamage(EntityDamageByEntityEvent event) + { + Entity damager = event.getDamager(); + Entity damaged = event.getEntity(); + + if (!(damager instanceof Player && damaged instanceof Horse)) + { + return; + } + + for (MountData data : GetValues()) + { + if (!damager.equals(data.getPlayer()) || !damaged.equals(data.getEntity())) + { + continue; + } + + event.setCancelled(true); + return; + } + } + + @EventHandler + public void horseInventoryClick(InventoryClickEvent event) + { + if (event.getClickedInventory() != null && event.getClickedInventory() instanceof HorseInventory) + { + event.setCancelled(true); + } + } + + @EventHandler + public void updateSkins(UpdateEvent event) + { + for (Player player : UtilServer.getPlayersCollection()) + { + MountData data = Get(player); + + if (data.getEntity() == null) + { + return; + } + + GemHuntersMountGadget gadget = (GemHuntersMountGadget) _gadget.getGameCosmeticManager().getActiveCosmetic( + player, + GameDisplay.GemHunters, + "Mount Skins" + ); + + if (gadget == null) + { + continue; + } + + gadget.getType().onUpdate(event, data.getEntity()); + } + } + + @EventHandler + public void gadgetEquip(GadgetEnableEvent event) + { + if (event.getGadget().getGadgetType() != GadgetType.GAME_MODIFIER) + { + event.setCancelled(true); + } + } + + public CosmeticManager getCosmeticManager() + { + return _cosmetic; + } + + public GadgetManager getGadgetManager() + { + return _gadget; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/command/MountSkinsCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/command/MountSkinsCommand.java new file mode 100644 index 00000000..148558ed --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/command/MountSkinsCommand.java @@ -0,0 +1,25 @@ +package mineplex.gemhunters.mount.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.gadget.gadgets.gamemodifiers.GameCosmeticCategory; +import mineplex.core.game.GameDisplay; +import mineplex.gemhunters.mount.MountModule; +import mineplex.gemhunters.mount.MountModule.Perm; + +public class MountSkinsCommand extends CommandBase +{ + + public MountSkinsCommand(MountModule plugin) + { + super(plugin, Perm.MOUNT_SKINS_COMMAND, "mount", "mounts", "skins", "mountskins"); + } + + @Override + public void Execute(Player caller, String[] args) + { + GameCosmeticCategory category = Plugin.getGadgetManager().getGameCosmeticManager().getCategoryFrom(GameDisplay.GemHunters, "Mount Skins"); + Plugin.getCosmeticManager().getShop().openPageForPlayer(caller, category.getGadgetPage(Plugin.getCosmeticManager(), caller)); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/command/SpawnMountCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/command/SpawnMountCommand.java new file mode 100644 index 00000000..9acb6f4a --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/mount/command/SpawnMountCommand.java @@ -0,0 +1,32 @@ +package mineplex.gemhunters.mount.command; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.command.CommandBase; +import mineplex.gemhunters.mount.MountData; +import mineplex.gemhunters.mount.MountModule; +import mineplex.gemhunters.mount.MountModule.Perm; + +public class SpawnMountCommand extends CommandBase +{ + + public SpawnMountCommand(MountModule plugin) + { + super(plugin, Perm.SPAWN_MOUNT_COMMAND, "spawnmount"); + } + + @Override + public void Execute(Player caller, String[] args) + { + MountData data = Plugin.Get(caller); + + if (data.getEntity() != null) + { + data.getEntity().remove(); + } + + Plugin.spawnHorse(caller, data, new ItemStack(Material.DIAMOND_BARDING), 0); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceData.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceData.java new file mode 100644 index 00000000..3ab3ed48 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceData.java @@ -0,0 +1,99 @@ +package mineplex.gemhunters.persistence; + +import mineplex.gemhunters.quest.QuestPlayerData; +import mineplex.serverdata.Region; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +public class PersistenceData +{ + + private final Region _region; + private final int _gems; + private final Location _location; + private final QuestPlayerData _questData; + private final int _health; + private final int _maxHealth; + private final int _hunger; + private final int _slots; + private final ItemStack[] _items; + private final ItemStack[] _armour; + private final long _saveTime; + private final int _cashOutTime; + + public PersistenceData(Region region, int gems, Location location, QuestPlayerData questData, int health, int maxHealth, int hunger, int slots, ItemStack[] items, ItemStack[] armour, long saveTime, int cashOutTime) + { + _region = region; + _gems = gems; + _location = location; + _questData = questData; + _health = health; + _maxHealth = maxHealth; + _hunger = hunger; + _items = items; + _slots = slots; + _armour = armour; + _saveTime = saveTime; + _cashOutTime = cashOutTime; + } + + public Region getRegion() + { + return _region; + } + + public int getGems() + { + return _gems; + } + + public Location getLocation() + { + return _location; + } + + public QuestPlayerData getQuestData() + { + return _questData; + } + + public int getHealth() + { + return _health; + } + + public int getMaxHealth() + { + return _maxHealth; + } + + public int getHunger() + { + return _hunger; + } + + public int getSlots() + { + return _slots; + } + + public ItemStack[] getItems() + { + return _items; + } + + public ItemStack[] getArmour() + { + return _armour; + } + + public long getSaveTime() + { + return _saveTime; + } + + public int getCashOutTime() + { + return _cashOutTime; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java new file mode 100644 index 00000000..6e51a998 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceModule.java @@ -0,0 +1,172 @@ +package mineplex.gemhunters.persistence; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import mineplex.core.common.util.UtilServer; +import mineplex.gemhunters.death.DeathModule; +import mineplex.serverdata.Region; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.CoreClient; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.F; +import mineplex.core.portal.events.ServerTransferEvent; +import mineplex.core.recharge.Recharge; +import mineplex.core.recharge.RechargeData; +import mineplex.gemhunters.death.event.QuitNPCDespawnEvent; +import mineplex.gemhunters.economy.CashOutModule; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.loot.InventoryModule; +import mineplex.gemhunters.quest.QuestModule; +import mineplex.gemhunters.quest.QuestPlayerData; + +@ReflectivelyCreateMiniPlugin +public class PersistenceModule extends MiniPlugin +{ + + private final CoreClientManager _client; + private final CashOutModule _cashOut; + private final DeathModule _death; + private final EconomyModule _economy; + private final QuestModule _quest; + private final InventoryModule _inventory; + + private final PersistenceRepository _repository; + + private final List _denyJoining; + + public PersistenceModule() + { + super("Persistence"); + + _client = require(CoreClientManager.class); + _cashOut = require(CashOutModule.class); + _death = require(DeathModule.class); + _quest = require(QuestModule.class); + _economy = require(EconomyModule.class); + _inventory = require(InventoryModule.class); + + _repository = new PersistenceRepository(); + + _denyJoining = Collections.synchronizedList(new ArrayList<>()); + } + + @EventHandler + public void preLogin(AsyncPlayerPreLoginEvent event) + { + if (_denyJoining.contains(event.getName())) + { + event.disallow(Result.KICK_OTHER, "Please wait a few seconds before connecting again."); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + CoreClient client = _client.Get(player); + + if (_death.isRespawning(player)) + { + return; + } + else if (_cashOut.isAboutToCashOut(player)) + { + runAsync(() -> + { + _denyJoining.add(player.getName()); + _repository.deletePersistence(client); + _denyJoining.remove(player.getName()); + }); + return; + } + + Region region = UtilServer.getRegion(); + int gems = _economy.Get(player); + Location location = player.getLocation(); + QuestPlayerData quest = _quest.Get(player); + int health = (int) player.getHealth(); + int maxHealth = (int) player.getMaxHealth(); + int hunger = player.getFoodLevel(); + int slots = _inventory.getSlots(player); + ItemStack[] items = player.getInventory().getContents(); + ItemStack[] armour = player.getInventory().getArmorContents(); + long saveTime = System.currentTimeMillis(); + int cashOutTime; + RechargeData rechargeData = Recharge.Instance.Get(player).get("Cash Out"); + + if (rechargeData == null) + { + cashOutTime = 0; + } + else + { + cashOutTime = (int) rechargeData.GetRemaining(); + } + + PersistenceData data = new PersistenceData(region, gems, location, quest, health, maxHealth, hunger, slots, items, armour, saveTime, cashOutTime); + + runAsync(() -> + { + _denyJoining.add(player.getName()); + _repository.savePersistence(client, data); + _denyJoining.remove(player.getName()); + }); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void playerDeath(PlayerDeathEvent event) + { + Player player = event.getEntity(); + CoreClient client = _client.Get(player); + + runAsync(() -> + { + _denyJoining.add(player.getName()); + _repository.deletePersistence(client); + _denyJoining.remove(player.getName()); + }); + } + + @EventHandler + public void npcDespawn(QuitNPCDespawnEvent event) + { + if (!event.isPluginRemove()) + { + runAsync(() -> + { + String name = event.getNpc().getName(); + _denyJoining.add(name); + _client.getOrLoadClient(event.getNpc().getName(), _repository::deletePersistence); + _denyJoining.remove(name); + }); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void serverTransfer(ServerTransferEvent event) + { + if (event.getServer().startsWith("GH-")) + { + event.getPlayer().sendMessage(F.main("Portal", "Sorry, in order to switch servers please use /hub.")); + event.setCancelled(true); + } + } + + public final PersistenceRepository getRepository() + { + return _repository; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceRepository.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceRepository.java new file mode 100644 index 00000000..3e9d8678 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/persistence/PersistenceRepository.java @@ -0,0 +1,254 @@ +package mineplex.gemhunters.persistence; + +import java.lang.reflect.Constructor; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.google.gson.Gson; + +import mineplex.core.account.CoreClient; +import mineplex.core.common.util.UtilServer; +import mineplex.gemhunters.quest.QuestPlayerData; +import mineplex.serverdata.Region; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.database.RepositoryBase; +import mineplex.serverdata.database.column.ColumnInt; +import mineplex.serverdata.database.column.ColumnTimestamp; +import mineplex.serverdata.database.column.ColumnVarChar; + +public class PersistenceRepository extends RepositoryBase +{ + + private static final String GET_DATA = "SELECT * FROM gemHunters WHERE accountId=? AND region=?;"; + private static final String INSERT_DATA = "INSERT INTO gemHunters (accountId, region, gems, health, maxHealth, hunger, x, y, z, yaw, pitch, quests, slots, items, armour, saveTime, cashOutTime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"; + private static final String UPDATE_DATA = "UPDATE gemHunters SET gems=?,health=?,maxHealth=?,hunger=?,x=?,y=?,z=?,yaw=?,pitch=?,quests=?,slots=?,items=?,armour=?,saveTime=?,cashOutTime=? WHERE accountId=? AND region=?;"; + private static final String DELETE_DATA = "DELETE FROM gemHunters WHERE accountId=?;"; + private static final Gson GSON; + private static final ItemStack AIR = new ItemStack(Material.AIR); + + static + { + GSON = new Gson(); + } + + private final List _exists; + + public PersistenceRepository() + { + super(DBPool.getAccount()); + + _exists = new ArrayList<>(); + } + + public void getPersistenceData(Consumer response, CoreClient client) + { + int accountId = client.getAccountId(); + Region region = UtilServer.getRegion(); + + executeQuery(GET_DATA, resultSet -> + { + if (resultSet.next()) + { + int gems = resultSet.getInt("gems"); + int health = resultSet.getInt("health"); + int maxHealth = resultSet.getInt("maxHealth"); + int hunger = resultSet.getInt("hunger"); + int x = resultSet.getInt("x"); + int y = resultSet.getInt("y"); + int z = resultSet.getInt("z"); + int yaw = resultSet.getInt("yaw"); + int pitch = resultSet.getInt("pitch"); + int slots = resultSet.getInt("slots"); + String quests = resultSet.getString("quests"); + QuestPlayerData questData = GSON.fromJson(quests, QuestPlayerData.class); + + String items = resultSet.getString("items"); + List> itemsMap = GSON.fromJson(items, List.class); + List itemsList = new ArrayList<>(itemsMap.size()); + + for (Map map : itemsMap) + { + ItemStack itemStack = CraftItemStack.deserialize(map); + + if (map.containsKey("meta")) + { + itemStack.setItemMeta(deserialiseMeta(map.get("meta"))); + } + + itemsList.add(itemStack); + } + + String armour = resultSet.getString("armour"); + List> armourMap = GSON.fromJson(armour, List.class); + List armourList = new ArrayList<>(armourMap.size()); + + for (Map map : armourMap) + { + ItemStack itemStack = CraftItemStack.deserialize(map); + + if (map.containsKey("meta")) + { + itemStack.setItemMeta(deserialiseMeta(map.get("meta"))); + } + + armourList.add(CraftItemStack.deserialize(map)); + } + + Timestamp saveTime = resultSet.getTimestamp("saveTime"); + + if (saveTime == null) + { + saveTime = new Timestamp(System.currentTimeMillis()); + } + + int cashOutTime = resultSet.getInt("cashOutTime"); + + _exists.add(accountId); + Location location = new Location(Bukkit.getWorlds().get(0), x, y, z, yaw, pitch); + + PersistenceData data = new PersistenceData(region, gems, location, questData, health, maxHealth, hunger, slots, itemsList.toArray(new ItemStack[0]), armourList.toArray(new ItemStack[0]), saveTime.getTime(), cashOutTime); + response.accept(data); + } + }, new ColumnInt("accountId", accountId), new ColumnVarChar("region", 2, region.toString())); + } + + public void savePersistence(CoreClient client, PersistenceData data) + { + int accountId = client.getAccountId(); + + Region region = data.getRegion(); + int gems = data.getGems(); + int health = data.getHealth(); + int maxHealth = data.getMaxHealth(); + int hunger = data.getHunger(); + int x = data.getLocation().getBlockX(); + int y = data.getLocation().getBlockY(); + int z = data.getLocation().getBlockZ(); + int yaw = (int) data.getLocation().getYaw(); + int pitch = (int) data.getLocation().getPitch(); + int slots = data.getSlots(); + ItemStack[] items = data.getItems(); + ItemStack[] armour = data.getArmour(); + List> itemsMap = new ArrayList<>(items.length); + List> armourMap = new ArrayList<>(armour.length); + Timestamp saveTime = new Timestamp(data.getSaveTime()); + int cashOutTime = data.getCashOutTime(); + + for (ItemStack itemStack : items) + { + if (itemStack == null || itemStack.getType() == Material.MAP || itemStack.getType() == Material.STAINED_GLASS_PANE) + { + itemStack = AIR; + } + + itemsMap.add(itemStack.serialize()); + } + + for (ItemStack itemStack : armour) + { + if (itemStack == null) + { + continue; + } + + armourMap.add(itemStack.serialize()); + } + + if (exists(client)) + { + executeUpdate(UPDATE_DATA, + new ColumnInt("gems", gems), + new ColumnInt("health", health), + new ColumnInt("maxHealth", maxHealth), + new ColumnInt("hunger", hunger), + new ColumnInt("x", x), + new ColumnInt("y", y), + new ColumnInt("z", z), + new ColumnInt("yaw", yaw), + new ColumnInt("pitch", pitch), + new ColumnVarChar("quests", 500, GSON.toJson(data.getQuestData())), + new ColumnInt("slots", slots), + new ColumnVarChar("items", 10000, GSON.toJson(itemsMap)), + new ColumnVarChar("armour", 1000, GSON.toJson(armourMap)), + new ColumnTimestamp("saveTime", saveTime), + new ColumnInt("cashOutTime", cashOutTime), + new ColumnInt("accountId", accountId), + new ColumnVarChar("region", 2, region.toString()) + ); + } + else + { + executeInsert(INSERT_DATA, null, + new ColumnInt("accountId", accountId), + new ColumnVarChar("region", 2, region.toString()), + new ColumnInt("gems", gems), + new ColumnInt("health", health), + new ColumnInt("maxHealth", maxHealth), + new ColumnInt("hunger", hunger), + new ColumnInt("x", x), + new ColumnInt("y", y), + new ColumnInt("z", z), + new ColumnInt("yaw", yaw), + new ColumnInt("pitch", pitch), + new ColumnVarChar("quests", 500, GSON.toJson(data.getQuestData())), + new ColumnInt("slots", slots), + new ColumnVarChar("items", 10000, GSON.toJson(itemsMap)), + new ColumnVarChar("armour", 1000, GSON.toJson(armourMap)), + new ColumnTimestamp("saveTime", saveTime), + new ColumnInt("cashOutTime", cashOutTime) + ); + } + + _exists.remove(Integer.valueOf(accountId)); + } + + public void deletePersistence(CoreClient client) + { + int accountId = client.getAccountId(); + + executeUpdate(DELETE_DATA, new ColumnInt("accountId", accountId)); + _exists.remove(Integer.valueOf(accountId)); + } + + public boolean exists(CoreClient client) + { + return _exists.contains(client.getAccountId()); + } + + private ItemMeta deserialiseMeta(Object map) + { + if (!(map instanceof Map)) + { + return null; + } + + try + { + Class clazz = Class.forName("org.bukkit.craftbukkit.v1_8_R3.inventory.CraftMetaItem"); + Constructor constructor = clazz.getDeclaredConstructor(Map.class); + + constructor.setAccessible(true); + + ItemMeta meta = (ItemMeta) constructor.newInstance(map); + meta.setDisplayName((String) ((Map) map).get("displayName")); + + return meta; + } + catch (Exception e) + { + e.printStackTrace(); + } + + return null; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatus.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatus.java new file mode 100644 index 00000000..7be18402 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatus.java @@ -0,0 +1,44 @@ +package mineplex.gemhunters.playerstatus; + +import mineplex.core.common.util.UtilTime; + +public class PlayerStatus +{ + + private PlayerStatusType _statusType; + private long _start; + private long _length; + + public PlayerStatus(PlayerStatusType statusType) + { + this(statusType, -1); + } + + public PlayerStatus(PlayerStatusType statusType, long length) + { + _statusType = statusType; + _start = System.currentTimeMillis(); + _length = length; + } + + public PlayerStatusType getStatusType() + { + return _statusType; + } + + public long getStart() + { + return _start; + } + + public long getLength() + { + return _length; + } + + public boolean isDone() + { + return _length > 0 && UtilTime.elapsed(_start, _length); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatusModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatusModule.java new file mode 100644 index 00000000..77f8fbe1 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatusModule.java @@ -0,0 +1,108 @@ +package mineplex.gemhunters.playerstatus; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import mineplex.core.MiniClientPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; + +@ReflectivelyCreateMiniPlugin +public class PlayerStatusModule extends MiniClientPlugin +{ + + private static final long COMBAT_TIME = TimeUnit.SECONDS.toMillis(30); + + private final PlayerStatus _default; + + public PlayerStatusModule() + { + super("Player Status"); + + _default = new PlayerStatus(PlayerStatusType.DANGER); + } + + @Override + protected PlayerStatus addPlayer(UUID uuid) + { + return _default; + } + + @EventHandler(priority = EventPriority.LOW) + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + PlayerStatus status = Get(player); + + if (status.isDone()) + { + Set(player, _default); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void entityDamage(EntityDamageByEntityEvent event) + { + if (event.isCancelled() || !(event.getEntity() instanceof Player)) + { + return; + } + + if (event.getDamager() instanceof Player) + { + setStatus((Player) event.getDamager(), PlayerStatusType.COMBAT, COMBAT_TIME); + } + + setStatus((Player) event.getEntity(), PlayerStatusType.COMBAT, COMBAT_TIME); + } + + @EventHandler + public void teleportMap(PlayerTeleportIntoMapEvent event) + { + setStatus(event.getPlayer(), PlayerStatusType.DANGER); + } + + public void setStatus(Player player, PlayerStatusType statusType) + { + setStatus(player, statusType, false); + } + + public void setStatus(Player player, PlayerStatusType statusType, long length) + { + setStatus(player, statusType, length, false); + } + + public void setStatus(Player player, PlayerStatusType statusType, boolean force) + { + setStatus(player, statusType, -1, force); + } + + public void setStatus(Player player, PlayerStatusType statusType, long length, boolean force) + { + PlayerStatus current = Get(player); + //Bukkit.broadcastMessage("Setting " + player.getName() + " -> " + statusType.getName() + " -> " + length); + + if (!force && current.getStatusType().hasPriority(statusType)) + { + return; + } + + Set(player, new PlayerStatus(statusType, length)); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatusType.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatusType.java new file mode 100644 index 00000000..8702de40 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/playerstatus/PlayerStatusType.java @@ -0,0 +1,22 @@ +package mineplex.gemhunters.playerstatus; + +public enum PlayerStatusType +{ + + DANGER, + SAFE, + COLD, + WARM, + COMBAT; + + public String getName() + { + return name().charAt(0) + name().substring(1).toLowerCase(); + } + + public boolean hasPriority(PlayerStatusType other) + { + return ordinal() > other.ordinal(); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/progression/ProgressionModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/progression/ProgressionModule.java new file mode 100644 index 00000000..e99457ac --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/progression/ProgressionModule.java @@ -0,0 +1,41 @@ +package mineplex.gemhunters.progression; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.util.C; + +import java.util.Arrays; +import java.util.List; + +@ReflectivelyCreateMiniPlugin +public class ProgressionModule extends MiniPlugin +{ + + private static final List TITLE_LIST = Arrays.asList( + new ProgressionTitle(C.cGray + "Bankrupt", 0), + new ProgressionTitle(C.cAqua + "Beggar", 100), + new ProgressionTitle(C.cGreen + "Poor", 250), + new ProgressionTitle(C.cGreen + "MiddleClass", 500), + new ProgressionTitle(C.cGold + "Wealthy", 750), + new ProgressionTitle(C.cGold + "Loaded", 1000), + new ProgressionTitle(C.cRed + "Millionaire", 5000) + ); + + public ProgressionModule() + { + super("Progression"); + } + + public ProgressionTitle getTitle(int gems) + { + for (ProgressionTitle title : TITLE_LIST) + { + if (title.getRequiredGems() >= gems) + { + return title; + } + } + + return TITLE_LIST.get(TITLE_LIST.size() - 1); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/progression/ProgressionTitle.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/progression/ProgressionTitle.java new file mode 100644 index 00000000..0e512e22 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/progression/ProgressionTitle.java @@ -0,0 +1,24 @@ +package mineplex.gemhunters.progression; + +public class ProgressionTitle +{ + + private String _title; + private int _requiredGems; + + public ProgressionTitle(String title, int requiredGems) + { + _title = title; + _requiredGems = requiredGems; + } + + public String getTitle() + { + return _title; + } + + public int getRequiredGems() + { + return _requiredGems; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/Quest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/Quest.java new file mode 100644 index 00000000..6ee6f826 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/Quest.java @@ -0,0 +1,161 @@ +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.currency.GlobalCurrency; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.donation.DonationManager; +import mineplex.core.inventory.InventoryManager; +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 InventoryManager _inventory; + protected final WorldDataModule _worldData; + + private final Map _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); + _inventory = Managers.require(InventoryManager.class); + _worldData = Managers.require(WorldDataModule.class); + + _counter = new HashMap<>(); + + UtilServer.RegisterEvents(this); + } + + @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) + { + } + + public void onReward(Player player) + { + if (_completeReward > 0) + { + _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 float getProgress(Player player) + { + return 0; + } + + 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; + } + + public String getRewardString() + { + return F.currency(GlobalCurrency.GEM, _completeReward); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestModule.java new file mode 100644 index 00000000..1c00e262 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestModule.java @@ -0,0 +1,535 @@ +package mineplex.gemhunters.quest; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +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.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilItem.ItemAttribute; +import mineplex.core.common.util.UtilMath; +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.stats.StatsManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.quest.command.ResetQuestsCommand; +import mineplex.gemhunters.quest.types.ChestOpenerQuest; +import mineplex.gemhunters.quest.types.EnjoyTheViewQuest; +import mineplex.gemhunters.quest.types.GiveItemQuest; +import mineplex.gemhunters.quest.types.KillMostValuableQuest; +import mineplex.gemhunters.quest.types.KillPlayerQuest; +import mineplex.gemhunters.quest.types.LocationQuest; +import mineplex.gemhunters.quest.types.SamitoDQuest; +import mineplex.gemhunters.quest.types.SpecificChestOpenerQuest; +import mineplex.gemhunters.quest.types.WalkingQuest; +import mineplex.gemhunters.world.WorldDataModule; + +@ReflectivelyCreateMiniPlugin +public class QuestModule extends MiniClientPlugin +{ + public enum Perm implements Permission + { + RESET_QUESTS_COMMAND, + } + + 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"; + + // -1 for the reward dictates that the quest's reward will be handled by the subclass + 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("10") + " gems to the Hobo.", 100, 300, 10), + + new KillPlayerQuest(4, "Mercenary", 50, -1, 5, "Mythical Chest"), + new KillPlayerQuest(5, "Warrior", 100, -1, 10, "Illuminated Chest"), + new KillPlayerQuest(6, "Slayer", 250, -1, 25, "Omega Chest"), + //new KillPlayerQuest(7, "Ruthless", 1000, -1, 50, "Rank Upgrade"), + + new LocationQuest(8, "Vision Quest", "Climb the tallest mountain.", 100, 300, "TALL_MOUNTAIN"), + new LocationQuest(9, "Emergency Medi-Vac", "Get to the helicopter on the roof of the hospital.", 50, 150, "HOSPITAL_HELI"), + + new SpecificChestOpenerQuest(10, "Treasure Hunter", "Open " + F.count("1") + " Legendary Chest.", 100, 5000, "PURPLE", 1), + new SpecificChestOpenerQuest(11, "Resupply", "Open a Supply Drop.", 100, 500, "RED", 1), + + new EnjoyTheViewQuest(12, 25, 100), + + new GiveItemQuest(13, "Waiter", "5 apples", 300, 750, new ItemStack(Material.APPLE), 5), + new GiveItemQuest(14, "The Golden Apple", "a Golden Apple", 200, 3000, new ItemStack(Material.GOLDEN_APPLE), 1), + + new WalkingQuest(15, "Going for a walk", "Go on a journey of " + F.count("1000") + " blocks.", 100, -1, 1000, Material.GOLD_BARDING), + new WalkingQuest(16, "Going on a journey", "Go on a journey of " + F.count("5000") + " blocks.", 200, -1, 5000, Material.DIAMOND_BARDING), + + new KillMostValuableQuest(17, "Equality", "Slay the most valuable player in the game.", 100, 1500), + + //new CraftingQuest(18, "Light em up", "Craft " + F.count("5 Torches"), 25, 250, Material.TORCH, 5) + }; + + private final EconomyModule _economy; + private final StatsManager _stats; + private final WorldDataModule _worldData; + + private QuestModule() + { + super("Quest"); + + _economy = require(EconomyModule.class); + _stats = require(StatsManager.class); + _worldData = require(WorldDataModule.class); + + Menu menu = new QuestUI(this); + + runSyncLater(() -> + { + for (Location location : _worldData.getCustomLocation("QUEST_NPC")) + { + new QuestNPC(this, location, menu); + } + }, 20); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.ADMIN.setPermission(Perm.RESET_QUESTS_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new ResetQuestsCommand(this)); + } + + @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; + } + + if (playerData.getLastClear() != 0) + { + 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, false); + + if (!able) + { + event.setCancelled(true); + } + else + { +// UUID owner = UUID.fromString(item.getMetadata(ITEM_METADATA).get(0).asString()); +// Player other = UtilPlayer.searchExact(owner); + + event.getItem().remove(); + event.setCancelled(true); + /* + * 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. + */ + } + } + + @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())); + } + + @EventHandler + public void playerDeath(PlayerDeathEvent event) + { + Get(event.getEntity()).clear(true); + } + + public void updateQuests(Player player) + { + QuestPlayerData playerData = Get(player); + List 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, boolean applyCost) + { + 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; + } + else if (!UtilInv.hasSpace(player, 1)) + { + player.sendMessage(F.main(_moduleName, "You do not have enough space in your inventory to start this quest.")); + return false; + } + else if (applyCost && _economy.Get(player) < quest.getStartCost()) + { + player.sendMessage(F.main(_moduleName, "You do not have enough gems to start this 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); + + quest.onStart(player); + + if (applyCost) + { + _economy.removeFromStore(player, quest.getStartCost()); + } + 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()) + ".")); + + _stats.incrementStat(player, "Gem Hunters.QuestsCompleted", 1); + + 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, boolean hasGems) + { + 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 (!hasGems) + { + builder.addLore(C.cRed + "You do not have enough gems to start 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 + { + String progress = C.mBody + "[" + C.cGreen + quest.get(player) + C.mBody + "/" + C.cGreen + quest.getGoal() + C.mBody + "]"; + + builder.addLore(UtilTextMiddle.progress(quest.getProgress(player)) + C.mBody + " " + progress); + } + + builder.addLore("", "Cost: " + F.currency(GlobalCurrency.GEM, quest.getStartCost()), "Reward: " + quest.getRewardString()); + + 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, true); + + for (ItemStack items : player.getInventory().getContents()) + { + if (UtilItem.isSimilar(itemStack, items, ItemAttribute.NAME, ItemAttribute.MATERIAL, ItemAttribute.DATA, ItemAttribute.AMOUNT)) + { + 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; + } + + public void setPlayerData(Player player, QuestPlayerData playerData) + { + Set(player, playerData); + } + + public boolean isQuestNPC(Entity entity) + { + return entity.hasMetadata("quest_npc"); + } + + @EventHandler + public void debug(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().startsWith("/questdatatest")) + { + event.setCancelled(true); + Player player = event.getPlayer(); + + QuestPlayerData playerData = Get(player); + + for (int i : playerData.getPossibleQuests()) + { + player.sendMessage("P: " + i); + } + + for (int i : playerData.getActiveQuests()) + { + player.sendMessage("A: " + i); + } + + for (int i : playerData.getCompletedQuests()) + { + player.sendMessage("C: " + i); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestNPC.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestNPC.java new file mode 100644 index 00000000..7c377c06 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestNPC.java @@ -0,0 +1,45 @@ +package mineplex.gemhunters.quest; + +import mineplex.core.common.util.C; +import mineplex.core.menu.Menu; +import mineplex.gemhunters.util.SimpleNPC; +import org.bukkit.Location; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Villager.Profession; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.metadata.FixedMetadataValue; + +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; + _entity.setMetadata("quest_npc", new FixedMetadataValue(quest.getPlugin(), true)); + + Villager villager = (Villager) _entity; + + villager.setProfession(Profession.LIBRARIAN); + } + + @Override + @EventHandler(priority = EventPriority.HIGH) + public void npcClick(PlayerInteractEntityEvent event) + { + if (event.isCancelled() || !event.getRightClicked().equals(_entity)) + { + return; + } + + event.setCancelled(true); + + _questMenu.open(event.getPlayer()); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestPlayerData.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestPlayerData.java new file mode 100644 index 00000000..7a2d5a75 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestPlayerData.java @@ -0,0 +1,65 @@ +package mineplex.gemhunters.quest; + +import java.util.ArrayList; +import java.util.List; + +public class QuestPlayerData +{ + + private final List _possibleQuests; + private final List _activeQuests; + private final List _completedQuests; + + private long _lastClear; + + public QuestPlayerData() + { + _possibleQuests = new ArrayList<>(); + _activeQuests = new ArrayList<>(); + _completedQuests = new ArrayList<>(); + + _lastClear = System.currentTimeMillis(); + } + + public void clear() + { + clear(false); + } + + public void clear(boolean active) + { + _possibleQuests.clear(); + _completedQuests.clear(); + + if (active) + { + _activeQuests.clear(); + _lastClear = 0; + } + else + { + _lastClear = System.currentTimeMillis(); + } + } + + public List getPossibleQuests() + { + return _possibleQuests; + } + + public List getActiveQuests() + { + return _activeQuests; + } + + public List getCompletedQuests() + { + return _completedQuests; + } + + public long getLastClear() + { + return _lastClear; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestUI.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestUI.java new file mode 100644 index 00000000..44e95781 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestUI.java @@ -0,0 +1,66 @@ +package mineplex.gemhunters.quest; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilUI; +import mineplex.core.menu.Button; +import mineplex.core.menu.Menu; +import mineplex.gemhunters.economy.EconomyModule; + +public class QuestUI extends Menu +{ + + private final EconomyModule _economy; + + public QuestUI(QuestModule plugin) + { + super("Quest Master", plugin); + + _economy = Managers.require(EconomyModule.class); + } + + @Override + protected Button[] setUp(Player player) + { + Button[] buttons = new Button[21]; + QuestPlayerData playerData = getPlugin().Get(player); + + int i = 0; + int[] slots = UtilUI.getIndicesFor(playerData.getPossibleQuests().size(), 1); + for (Integer id : playerData.getPossibleQuests()) + { + Quest quest = getPlugin().getFromId(id); + ItemStack itemStack = getPlugin().getItemStack(quest, player, true, UtilInv.hasSpace(player, 1), _economy.Get(player) >= quest.getStartCost()); + + buttons[slots[i++]] = new QuestSelectButton(getPlugin(), itemStack, quest); + } + + return buttons; + } + + public class QuestSelectButton extends Button + { + + private final Quest _quest; + + public QuestSelectButton(QuestModule plugin, ItemStack itemStack, Quest quest) + { + super(itemStack, plugin); + + _quest = quest; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + getPlugin().startQuest(_quest, player, true); + resetAndUpdate(); + } + + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/command/ResetQuestsCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/command/ResetQuestsCommand.java new file mode 100644 index 00000000..3449e1ad --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/command/ResetQuestsCommand.java @@ -0,0 +1,44 @@ +package mineplex.gemhunters.quest.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.gemhunters.quest.QuestModule; +import mineplex.gemhunters.quest.QuestPlayerData; + +public class ResetQuestsCommand extends CommandBase +{ + public ResetQuestsCommand(QuestModule plugin) + { + super(plugin, QuestModule.Perm.RESET_QUESTS_COMMAND, "resetquest"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Player target = caller; + + if (args.length > 0) + { + Player arg = UtilPlayer.searchOnline(target, args[0], true); + target = arg == null ? target : arg; + } + + if (caller.equals(target)) + { + caller.sendMessage(F.main(Plugin.getName(), "Reset your quests.")); + } + else + { + caller.sendMessage(F.main(Plugin.getName(), "You reset " + F.elem(target.getName() + "'s") + " quests.")); + target.sendMessage(F.main(Plugin.getName(), F.elem(caller.getName()) + " reset your quests.")); + } + + QuestPlayerData playerData = Plugin.Get(target); + + playerData.clear(); + Plugin.updateQuests(target); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/ChestOpenerQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/ChestOpenerQuest.java new file mode 100644 index 00000000..ab181664 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/ChestOpenerQuest.java @@ -0,0 +1,52 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.gemhunters.loot.event.PlayerChestOpenEvent; +import mineplex.gemhunters.quest.Quest; + +public class ChestOpenerQuest extends Quest +{ + + private final int _goal; + + public ChestOpenerQuest(int id, String name, int startCost, int completeReward, int goal) + { + super(id, name, "Open " + F.count(String.valueOf(goal)) + " Chests.", startCost, completeReward); + + _goal = goal; + } + + @Override + public float getProgress(Player player) + { + return (float) get(player) / (float) _goal; + } + + @Override + public int getGoal() + { + return _goal; + } + + @EventHandler + public void chestOpen(PlayerChestOpenEvent event) + { + Player player = event.getPlayer(); + + if (!isActive(player)) + { + return; + } + + int amount = getAndIncrement(player, 1); + + if (amount >= _goal) + { + onReward(player); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/CraftingQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/CraftingQuest.java new file mode 100644 index 00000000..e2bc9d9e --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/CraftingQuest.java @@ -0,0 +1,39 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.gemhunters.quest.Quest; + +public class CraftingQuest extends Quest +{ + + private final Material _material; + private final int _amount; + + public CraftingQuest(int id, String name, String description, int startCost, int completeReward, Material material, int amount) + { + super(id, name, description, startCost, completeReward); + + _material = material; + _amount = amount; + } + + @EventHandler + public void craft(CraftItemEvent event) + { + ItemStack result = event.getRecipe().getResult(); + + if (result.getType() == _material) + { + if (getAndIncrement((Player) event.getWhoClicked(), result.getAmount()) >= _amount) + { + onReward((Player) event.getWhoClicked()); + } + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/EnjoyTheViewQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/EnjoyTheViewQuest.java new file mode 100644 index 00000000..44cde406 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/EnjoyTheViewQuest.java @@ -0,0 +1,51 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.UtilBlock; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.quest.Quest; + +public class EnjoyTheViewQuest extends Quest +{ + + private static final int HEIGHT_GOAL = 120; + private static final int TIME_MIN = 12500; + private static final int TIME_MAX = 13000; + + public EnjoyTheViewQuest(int id, int startCost, int completeReward) + { + super(id, "Enjoy The View", "Climb to the roof of a skyscraper and watch the sun set.", startCost, completeReward); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + long time = _worldData.World.getTime(); + + if (time < TIME_MIN || time > TIME_MAX) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + // active and above 120 and they are on the top block (on the roof) + if (!isActive(player) || player.getLocation().getBlockY() < HEIGHT_GOAL || UtilBlock.getHighest(_worldData.World, player.getLocation().getBlock()).getLocation().getBlockY() > player.getLocation().getBlockY()) + { + continue; + } + + onReward(player); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/GiveItemQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/GiveItemQuest.java new file mode 100644 index 00000000..c879e1f7 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/GiveItemQuest.java @@ -0,0 +1,81 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.gemhunters.quest.Quest; + +public class GiveItemQuest extends Quest +{ + + private final ItemStack _required; + private final int _amount; + + public GiveItemQuest(int id, String name, String description, int startCost, int completeReward, ItemStack required, int amount) + { + super(id, name, "Bring the " + F.name("Quest Master ") + description, startCost, completeReward); + + _required = required; + _amount = amount; + } + + @Override + public float getProgress(Player player) + { + return (float) get(player) / (float) _amount; + } + + @Override + public int getGoal() + { + return _amount; + } + + @EventHandler + public void entityClick(PlayerInteractEntityEvent event) + { + if (!_quest.isQuestNPC(event.getRightClicked())) + { + return; + } + + Player player = event.getPlayer(); + + if (!isActive(player)) + { + return; + } + + ItemStack itemStack = player.getItemInHand(); + + if (itemStack == null || !itemStack.isSimilar(_required)) + { + return; + } + + int amount = get(player); + + while (itemStack != null && amount < _amount) + { + itemStack = UtilInv.decrement(itemStack); + amount++; + getAndIncrement(player, 1); + } + + player.setItemInHand(itemStack); + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1.1F); + event.setCancelled(true); + + if (amount >= _amount) + { + onReward(player); + return; + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/KillMostValuableQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/KillMostValuableQuest.java new file mode 100644 index 00000000..0ab0f6fa --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/KillMostValuableQuest.java @@ -0,0 +1,83 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.PlayerDeathEvent; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.quest.Quest; + +public class KillMostValuableQuest extends Quest +{ + + public KillMostValuableQuest(int id, String name, String description, int startCost, int completeReward) + { + super(id, name, description, startCost, completeReward); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + Player player = getMostValuable(); + String display = C.cRed + "The most valuable player is " + C.cYellow + (player != null ? player.getName() : "No one"); + + for (Player other : Bukkit.getOnlinePlayers()) + { + if (!isActive(other) || !_quest.getItemStack(this, other, false, true, true).isSimilar(other.getItemInHand())) + { + continue; + } + + UtilTextBottom.display(display, other); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerDeath(PlayerDeathEvent event) + { + Player player = getMostValuable(); + + if (player == null || !event.getEntity().equals(player)) + { + return; + } + + Player killer = player.getKiller(); + + if (!isActive(killer)) + { + return; + } + + onReward(killer); + } + + private Player getMostValuable() + { + Player mostGemsPlayer = null; + int mostGems = 0; + + for (Player player : Bukkit.getOnlinePlayers()) + { + int gems = _economy.Get(player); + + if (gems > mostGems) + { + mostGemsPlayer = player; + mostGems = gems; + } + } + + return mostGemsPlayer; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/KillPlayerQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/KillPlayerQuest.java new file mode 100644 index 00000000..b978e4b0 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/KillPlayerQuest.java @@ -0,0 +1,71 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.gemhunters.economy.event.PlayerEarnGemsEvent; +import mineplex.gemhunters.loot.rewards.LootRankReward; +import mineplex.gemhunters.quest.Quest; + +public class KillPlayerQuest extends Quest +{ + + private final int _goal; + private final String _chest; + + public KillPlayerQuest(int id, String name, int startCost, int completeReward, int goal, String chest) + { + super(id, name, "Kill " + F.count(String.valueOf(goal)) + " players", startCost, completeReward); + + _goal = goal; + _chest = chest; + } + + @Override + public float getProgress(Player player) + { + return (float) get(player) / (float) _goal; + } + + @Override + public int getGoal() + { + return _goal; + } + + @Override + public String getRewardString() + { + return C.cAqua + _chest; + } + + @EventHandler + public void earnGems(PlayerEarnGemsEvent event) + { + Player player = event.getPlayer(); + + if (!isActive(player) || event.getReason() == null || !event.getReason().startsWith("Killing")) + { + return; + } + + int amount = getAndIncrement(player, 1); + + if (amount >= _goal) + { + if (_chest.equals("Rank Upgrade")) + { + new LootRankReward(null).success(); + } + else + { + _inventory.addItemToInventory(player, _chest, 1); + } + + onReward(player); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/LocationQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/LocationQuest.java new file mode 100644 index 00000000..fdfbc5d9 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/LocationQuest.java @@ -0,0 +1,46 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.quest.Quest; + +public class LocationQuest extends Quest +{ + + private static final int DISTANCE_SQUARED = 100; + + private final Location _goal; + + public LocationQuest(int id, String name, String description, int startCost, int completeReward, String locationKey) + { + super(id, name, description, startCost, completeReward); + + _goal = _worldData.getCustomLocation(locationKey).get(0); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOW) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (!isActive(player) || UtilMath.offsetSquared(player.getLocation(), _goal) > DISTANCE_SQUARED) + { + continue; + } + + onReward(player); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/SamitoDQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/SamitoDQuest.java new file mode 100644 index 00000000..846da455 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/SamitoDQuest.java @@ -0,0 +1,76 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.gemhunters.quest.Quest; + +public class SamitoDQuest extends Quest +{ + + private static final String NPC_NAME = "Hobo"; + private static final String[] REACTIONS = { + "Well hello there folks and welcome... to... my... youtube channel", + "WILLIAMMMMMMM", + "ALEXXXXXXXXXX", + "CHISS", + "Rods and Gaps", + "Hit him with that w-tap", + "You're the one who wanted to bring out bows young man" + }; + + private final Location _pot; + private final int _gemsToDonate; + + public SamitoDQuest(int id, String name, String description, int startCost, int completeReward, int gemsToDonate) + { + super(id, name, description, startCost, completeReward); + + _pot = _worldData.getCustomLocation("QUEST_SAM").get(0); + _pot.getBlock().setType(Material.FLOWER_POT); + + _gemsToDonate = gemsToDonate; + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (event.isCancelled() || !isActive(player)) + { + return; + } + + Block block = event.getClickedBlock(); + + if (block == null) + { + return; + } + + if (UtilMath.offsetSquared(block.getLocation(), _pot) < 16) + { + if (_economy.getGems(player) < _gemsToDonate) + { + player.sendMessage(F.main(NPC_NAME, "Awww come on man, even alex has more gems than you.")); + return; + } + + player.sendMessage(F.main(NPC_NAME, REACTIONS[UtilMath.random.nextInt(REACTIONS.length)])); + _economy.removeFromStore(player, _gemsToDonate); + UtilFirework.playFirework(_pot, Type.BURST, Color.GREEN, true, false); + onReward(player); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/SpecificChestOpenerQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/SpecificChestOpenerQuest.java new file mode 100644 index 00000000..336470d1 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/SpecificChestOpenerQuest.java @@ -0,0 +1,39 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.gemhunters.loot.event.PlayerChestOpenEvent; +import mineplex.gemhunters.quest.Quest; + +public class SpecificChestOpenerQuest extends Quest +{ + + private final String _colour; + private final int _amount; + + public SpecificChestOpenerQuest(int id, String name, String description, int startCost, int completeReward, String colour, int amount) + { + super(id, name, description, startCost, completeReward); + + _colour = colour; + _amount = amount; + } + + @EventHandler + public void chestOpen(PlayerChestOpenEvent event) + { + Player player = event.getPlayer(); + + if (!isActive(player) || !event.getProperties().getDataKey().equals(_colour)) + { + return; + } + + if (getAndIncrement(player, 1) >= _amount) + { + onReward(player); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/WalkingQuest.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/WalkingQuest.java new file mode 100644 index 00000000..b476eaeb --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/WalkingQuest.java @@ -0,0 +1,115 @@ +package mineplex.gemhunters.quest.types; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.Managers; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilMath; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.loot.LootItem; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.quest.Quest; +import mineplex.gemhunters.safezone.SafezoneModule; + +public class WalkingQuest extends Quest +{ + + private final SafezoneModule _safezone; + private final LootModule _loot; + + private final Map _last; + private final int _distance; + private final Material _itemReward; + + public WalkingQuest(int id, String name, String description, int startCost, int completeReward, int distance, Material itemReward) + { + super(id, name, description, startCost, completeReward); + + _safezone = Managers.require(SafezoneModule.class); + _loot = Managers.require(LootModule.class); + + _last = new HashMap<>(); + _distance = distance; + _itemReward = itemReward; + } + + @Override + public void onStart(Player player) + { + super.onStart(player); + + _last.put(player.getUniqueId(), player.getLocation()); + } + + @Override + public void onReward(Player player) + { + for (LootItem lootItem : _loot.getChestItems("RED")) + { + if (lootItem.getItemStack().getType() == _itemReward) + { + player.getInventory().addItem(lootItem.getItemStack()); + break; + } + } + + super.onReward(player); + } + + @Override + public String getRewardString() + { + return C.cAqua + ItemStackFactory.Instance.GetName(_itemReward, (byte) 0, false) + " Mount"; + } + + @Override + public float getProgress(Player player) + { + return (float) get(player) / (float) _distance; + } + + @Override + public int getGoal() + { + return _distance; + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOW) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (!isActive(player) || _safezone.isInSafeZone(player.getLocation())) + { + continue; + } + + int distance = (int) UtilMath.offset(_last.get(player.getUniqueId()), player.getLocation()); + int total = getAndIncrement(player, distance); + + if (total >= _distance) + { + _last.remove(player.getUniqueId()); + onReward(player); + return; + } + + _last.put(player.getUniqueId(), player.getLocation()); + } + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/safezone/SafezoneModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/safezone/SafezoneModule.java new file mode 100644 index 00000000..22dc510c --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/safezone/SafezoneModule.java @@ -0,0 +1,291 @@ +package mineplex.gemhunters.safezone; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import mineplex.core.recharge.Recharge; +import mineplex.gemhunters.death.event.QuitNPCSpawnEvent; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.playerstatus.PlayerStatus; +import mineplex.gemhunters.playerstatus.PlayerStatusModule; +import mineplex.gemhunters.playerstatus.PlayerStatusType; +import mineplex.gemhunters.world.WorldDataModule; + +@ReflectivelyCreateMiniPlugin +public class SafezoneModule extends MiniPlugin +{ + + public static final String SAFEZONE_DATA_PREFIX = "SAFEZONE"; + public static final String SAFEZONE_DATA_IGNORE = "IGNORE"; + + private final PlayerStatusModule _playerStatus; + private final WorldDataModule _worldData; + + private final Map _currentSafezone; + + private SafezoneModule() + { + super("Safezone"); + + _playerStatus = require(PlayerStatusModule.class); + _worldData = require(WorldDataModule.class); + + _currentSafezone = new HashMap<>(); + } + + @EventHandler + public void updateSafeZone(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + UUID key = player.getUniqueId(); + String oldSafezone = _currentSafezone.get(key); + boolean isInOldSafezone = oldSafezone != null; + String newSafezone = getSafezone(player.getLocation()); + boolean isInNewSafezone = newSafezone != null; + + // null -> not null + if (!isInOldSafezone && isInNewSafezone) + { + if (!newSafezone.contains(SAFEZONE_DATA_IGNORE)) + { + UtilTextMiddle.display("", C.cYellow + "Entering " + newSafezone, 10, 40, 10, player); + } + _currentSafezone.put(key, newSafezone); + } + // not null -> null + else if (isInOldSafezone && !isInNewSafezone) + { + if (!oldSafezone.contains(SAFEZONE_DATA_IGNORE)) + { + UtilTextMiddle.display("", C.cYellow + "Leaving " + oldSafezone, 10, 40, 10, player); + } + _playerStatus.setStatus(player, PlayerStatusType.DANGER, true); + _currentSafezone.remove(key); + } + } + } + + @EventHandler + public void updatePlayerStatus(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (!isInSafeZone(player.getLocation())) + { + continue; + } + + PlayerStatus current = _playerStatus.Get(player); + + if (current.getStatusType() == PlayerStatusType.DANGER) + { + if (getSafezone(player.getLocation()).contains(SAFEZONE_DATA_IGNORE)) + { + _playerStatus.setStatus(player, PlayerStatusType.SAFE, true); + } + else if (Recharge.Instance.usable(player, "Cash Out")) + { + _playerStatus.setStatus(player, PlayerStatusType.SAFE); + } + } + } + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + _currentSafezone.remove(player.getUniqueId()); + } + + @EventHandler + public void quitNpcSpawn(QuitNPCSpawnEvent event) + { + String safezone = getSafezone(event.getPlayer().getLocation()); + + if (safezone != null && safezone.contains(SAFEZONE_DATA_IGNORE)) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void entityDamage(EntityDamageEvent event) + { + if (!(event.getEntity() instanceof Player)) + { + return; + } + + Player player = (Player) event.getEntity(); + + if (isInSafeZone(player) && _playerStatus.Get(player).getStatusType() != PlayerStatusType.COMBAT) + { + event.setCancelled(true); + } + + if (!Recharge.Instance.usable(player, "Cash Out")) + { + event.setCancelled(false); + } + } + + @EventHandler + public void entityAttack(EntityDamageByEntityEvent event) + { + // Handle people shooting arrows at people outside a safezone + if (event.getDamager() instanceof Projectile) + { + Projectile projectile = (Projectile) event.getDamager(); + + if (projectile.getShooter() instanceof LivingEntity) + { + LivingEntity entity = (LivingEntity) projectile.getShooter(); + + if (isInSafeZone(entity.getLocation())) + { + event.setCancelled(true); + return; + } + } + } + + if (!(event.getDamager() instanceof Player)) + { + return; + } + + Player player = (Player) event.getDamager(); + + if (isInSafeZone(player)) + { + event.setCancelled(true); + } + } + + @EventHandler + public void hungerChange(FoodLevelChangeEvent event) + { + if (isInSafeZone(event.getEntity()) && event.getEntity() instanceof Player) + { + Player player = (Player) event.getEntity(); + + if (player.getFoodLevel() < event.getFoodLevel()) + { + return; + } + + event.setCancelled(true); + } + } + + @EventHandler + public void flintAndSteelInteract(PlayerInteractEvent event) + { + if (event.getItem() == null || event.getItem().getType() != Material.FLINT_AND_STEEL || event.getClickedBlock() == null || !isInSafeZone(event.getClickedBlock().getLocation())) + { + return; + } + + event.setCancelled(true); + } + + public boolean isInSafeZone(HumanEntity player) + { + return isInSafeZone(player.getLocation()) && _playerStatus.Get((Player) player).getStatusType() != PlayerStatusType.COMBAT; + } + + public boolean isInSafeZone(Location location) + { + return getSafezone(location) != null; + } + + public boolean isInSafeZone(Location location, String safezone) + { + if (safezone == null) + { + return false; + } + + List bounds = _worldData.getCustomLocation(SAFEZONE_DATA_PREFIX + " " + safezone); + + if (bounds == null || bounds.size() != 2) + { + log("Error regarding safezone bounds for region " + safezone + " there are " + bounds.size() + " points instead of 2. Ignoring this safezone!"); + return false; + } + + return UtilAlg.inBoundingBox(location, bounds.get(0), bounds.get(1)); + } + + public String getSafezone(Location location) + { + Map> customLocations = _worldData.getAllCustomLocations(); + + for (String key : customLocations.keySet()) + { + if (!key.startsWith(SAFEZONE_DATA_PREFIX)) + { + continue; + } + + List bounds = customLocations.get(key); + + if (bounds.size() != 2) + { + log("Error regarding safezone bounds for region " + key + " there are " + bounds.size() + " points instead of 2. Ignoring this safezone!"); + continue; + } + + if (UtilAlg.inBoundingBox(location, bounds.get(0), bounds.get(1))) + { + String name = ""; + String[] split = key.split(" "); + + for (int i = 1; i < split.length; i++) + { + name += split[i] + " "; + } + + return name.trim(); + } + } + + return null; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/scoreboard/GemHuntersScoreboard.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/scoreboard/GemHuntersScoreboard.java new file mode 100644 index 00000000..ba3067ae --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/scoreboard/GemHuntersScoreboard.java @@ -0,0 +1,72 @@ +package mineplex.gemhunters.scoreboard; + +import mineplex.gemhunters.progression.ProgressionModule; +import mineplex.gemhunters.progression.ProgressionTitle; +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.core.scoreboard.WritableMineplexScoreboard; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.playerstatus.PlayerStatus; +import mineplex.gemhunters.playerstatus.PlayerStatusModule; +import mineplex.gemhunters.supplydrop.SupplyDropModule; + +public class GemHuntersScoreboard extends WritableMineplexScoreboard +{ + + private final EconomyModule _economy; + private final PlayerStatusModule _playerStatus; + private final ProgressionModule _progression; + private final SupplyDropModule _supplyDrop; + + public GemHuntersScoreboard(Player player) + { + super(player); + + _economy = Managers.get(EconomyModule.class); + _playerStatus = Managers.get(PlayerStatusModule.class); + _progression = Managers.get(ProgressionModule.class); + _supplyDrop = Managers.get(SupplyDropModule.class); + } + + public void writeContent(Player player) + { + writeNewLine(); + + write(C.cGreenB + "Gems Earned"); + write(String.valueOf(_economy.getGems(player))); + + writeNewLine(); + + write(C.cGoldB + "Supply Drop"); + if (_supplyDrop.isActive()) + { + write(_supplyDrop.getActive().getName() + " - " + (int) UtilMath.offset(player.getLocation(), _supplyDrop.getActive().getChestLocation()) + "m"); + } + else + { + write(UtilTime.MakeStr(_supplyDrop.getLastSupplyDrop() + _supplyDrop.getSequenceTimer() - System.currentTimeMillis())); + } + + writeNewLine(); + + write(C.cYellowB + "Player Status"); + PlayerStatus status = _playerStatus.Get(player); + write(status.getStatusType().getName() + (status.getLength() > 0 ? " (" + (status.getStart() + status.getLength() - System.currentTimeMillis()) / 1000 + ")" : "")); + + writeNewLine(); + } + + public int getUndernameScore(Player player) + { + return _economy.getGems(player); + } + + public String getPrefix(Player perspective, Player subject) + { + return _progression.getTitle(_economy.getGems(subject)).getTitle() + " " + C.cYellow; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/scoreboard/ScoreboardModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/scoreboard/ScoreboardModule.java new file mode 100644 index 00000000..6b6e90b2 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/scoreboard/ScoreboardModule.java @@ -0,0 +1,227 @@ +package mineplex.gemhunters.scoreboard; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.economy.EconomyModule; + +@ReflectivelyCreateMiniPlugin +public class ScoreboardModule extends MiniPlugin +{ + + private static final String PRIMARY_COLOUR = C.cGreenB; + private static final String SECONDARY_COLOUR = C.cWhiteB; + private static final String TRANSITION_COLOUR = C.cDGreenB; + private static final String SCOREBOARD_TITLE = " GEM HUNTERS "; + + private final EconomyModule _economy; + + private final Map _scoreboards; + + private int _shineIndex; + private boolean _shineDirection = true; + + public ScoreboardModule() + { + super("Scoreboard"); + + _economy = require(EconomyModule.class); + _scoreboards = new HashMap<>(); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() == UpdateType.FAST) + { + for (UUID key : _scoreboards.keySet()) + { + GemHuntersScoreboard scoreboard = _scoreboards.get(key); + Player player = UtilPlayer.searchExact(key); + + scoreboard.writeContent(player); + scoreboard.draw(); + } + } + else if (event.getType() == UpdateType.FASTEST) + { + updateTitles(); + } + else if (event.getType() == UpdateType.SEC_08) + { + for (Player player : Bukkit.getOnlinePlayers()) + { + int gems = _economy.getGems(player); + + for (GemHuntersScoreboard scoreboard : _scoreboards.values()) + { + Objective objective = scoreboard.getHandle().getObjective(DisplaySlot.BELOW_NAME); + Score score = objective.getScore(player.getName()); + + if (score.getScore() == gems) + { + continue; + } + + score.setScore(gems); + } + } + } + } + + @EventHandler + public void playerJoin(PlayerJoinEvent event) + { + createPlayerScoreboard(event.getPlayer()); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + for (GemHuntersScoreboard scoreboard : _scoreboards.values()) + { + scoreboard.getHandle().getTeam(player.getName()).unregister(); + } + + _scoreboards.remove(player.getUniqueId()); + } + + @EventHandler + public void updateScoreboard(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC_20) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + createPlayerScoreboard(player); + } + } + + public void createPlayerScoreboard(Player player) + { + GemHuntersScoreboard scoreboard; + + if (_scoreboards.containsKey(player.getUniqueId())) + { + scoreboard = _scoreboards.get(player.getUniqueId()); + } + else + { + scoreboard = new GemHuntersScoreboard(player); + _scoreboards.put(player.getUniqueId(), scoreboard); + + // Gem Counter Undername + Objective gemCounter = scoreboard.getHandle().registerNewObjective("Gems", "Gems"); + gemCounter.setDisplaySlot(DisplaySlot.BELOW_NAME); + } + + Scoreboard handle = scoreboard.getHandle(); + + for (GemHuntersScoreboard other : _scoreboards.values()) + { + // Set the other player's name tag for the player joining + Player otherPlayer = other.getOwner(); + Team team = handle.getTeam(otherPlayer.getName()); + + if (team == null) + { + team = handle.registerNewTeam(otherPlayer.getName()); + } + + team.setPrefix(scoreboard.getPrefix(player, otherPlayer)); + //team.setSuffix(scoreboard.getSuffix(player, otherPlayer)); + team.addEntry(otherPlayer.getName()); + + if (player.equals(otherPlayer)) + { + continue; + } + + // Set the player that is joining + Scoreboard otherHandle = other.getHandle(); + Team otherTeam = otherHandle.getTeam(player.getName()); + + if (otherTeam == null) + { + otherTeam = otherHandle.registerNewTeam(player.getName()); + } + + otherTeam.setPrefix(other.getPrefix(other.getOwner(), player)); + //otherTeam.setSuffix(other.getSuffix(other.getOwner(), player)); + otherTeam.addEntry(player.getName()); + } + + player.setScoreboard(handle); + } + + public void updateTitles() + { + String out = (_shineDirection ? PRIMARY_COLOUR : SECONDARY_COLOUR); + + for (int i = 0; i < SCOREBOARD_TITLE.length(); i++) + { + char c = SCOREBOARD_TITLE.charAt(i); + + if (_shineDirection) + { + if (i == _shineIndex) + { + out += TRANSITION_COLOUR; + } + else if (i == _shineIndex + 1) + { + out += SECONDARY_COLOUR; + } + } + else + { + if (i == _shineIndex) + { + out += TRANSITION_COLOUR; + } + else if (i == _shineIndex + 1) + { + out += PRIMARY_COLOUR; + } + } + + out += c; + } + + for (GemHuntersScoreboard scoreboard : _scoreboards.values()) + { + scoreboard.setSidebarName(out); + } + + _shineIndex++; + + if (_shineIndex == SCOREBOARD_TITLE.length() * 2) + { + _shineIndex = 0; + _shineDirection = !_shineDirection; + } + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/SellingNPC.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/SellingNPC.java new file mode 100644 index 00000000..4e6ff241 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/SellingNPC.java @@ -0,0 +1,223 @@ +package mineplex.gemhunters.shop; + +import mineplex.core.Managers; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.util.SimpleNPC; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class SellingNPC extends SimpleNPC +{ + + private static final ItemStack CANCEL = new ItemBuilder(Material.REDSTONE_BLOCK) + .setTitle(C.cRedB + "Cancel") + .addLore("", "Click to cancel and return your items.") + .build(); + private static final ItemStack BUFFER = new ItemBuilder(Material.STAINED_GLASS_PANE, (byte) 15) + .setTitle(" ") + .build(); + + private final EconomyModule _economy; + + private final Set _selling; + private final Map _inv; + + private int _total; + + public SellingNPC(JavaPlugin plugin, Location spawn, Class type, String name, boolean vegetated, Set selling) + { + super(plugin, spawn, type, name, null, vegetated); + + _economy = Managers.require(EconomyModule.class); + + _selling = selling; + _inv = new HashMap<>(); + } + + @Override + @EventHandler + public void npcClick(PlayerInteractEntityEvent event) + { + super.npcClick(event); + + if (event.getRightClicked().equals(_entity)) + { + event.setCancelled(true); + + Player player = event.getPlayer(); + Inventory inv = UtilServer.getServer().createInventory(null, 54, _entity.getCustomName()); + + inv.setItem(0, CANCEL); + inv.setItem(8, getConfirm()); + + for (int i = 9; i < 18; i++) + { + inv.setItem(i, BUFFER); + } + + _inv.put(player, inv); + player.openInventory(inv); + } + } + + + @EventHandler + public void inventoryClick(InventoryClickEvent event) + { + if (event.getInventory() == null) + { + return; + } + + Player player = (Player) event.getWhoClicked(); + Inventory inv = _inv.get(player); + + if (inv == null | !event.getInventory().equals(inv)) + { + return; + } + + ItemStack itemStack = event.getCurrentItem(); + ItemStack cursor = event.getCursor(); + + if (itemStack == null || cursor == null) + { + return; + } + + Material type = itemStack.getType(); + + if (type == Material.EMERALD_BLOCK || type == Material.REDSTONE_BLOCK || type == Material.STAINED_GLASS_PANE) + { + if (type == Material.EMERALD_BLOCK) + { + finalise(player); + } + else if (type == Material.REDSTONE_BLOCK) + { + cancel(player); + } + + event.setCancelled(true); + return; + } + + TradeableItem currentItem = fromItemStack(itemStack); + TradeableItem cursorItem = fromItemStack(cursor); + + if (currentItem == null && cursorItem == null) + { + event.setCancelled(true); + player.playSound(player.getLocation(), Sound.VILLAGER_NO, 1, 0.7F); + player.sendMessage(F.main("Shop", "You cannot sell that item.")); + return; + } + + UtilServer.runSyncLater(() -> recalculatePrice(inv), 1); + } + + @EventHandler + public void inventoryClose(InventoryCloseEvent event) + { + Player player = (Player) event.getPlayer(); + + if (_inv.containsKey(player)) + { + cancel(player); + } + } + + private void recalculatePrice(Inventory inv) + { + int price = 0; + + for (ItemStack itemStack : inv.getContents()) + { + TradeableItem tradeableItem = fromItemStack(itemStack); + + if (tradeableItem == null) + { + continue; + } + + price += tradeableItem.getCost() * itemStack.getAmount(); + } + + _total = price; + inv.setItem(8, getConfirm()); + } + + private void finalise(Player player) + { + recalculatePrice(_inv.remove(player)); + player.closeInventory(); + player.playSound(player.getLocation(), Sound.VILLAGER_YES, 1, 0.7F); + _economy.addToStore(player, "Sold Items", _total); + } + + private void cancel(Player player) + { + Inventory inv = _inv.remove(player); + + for (ItemStack itemStack : inv.getContents()) + { + TradeableItem tradeableItem = fromItemStack(itemStack); + + if (tradeableItem == null) + { + continue; + } + + player.getInventory().addItem(itemStack); + } + + player.closeInventory(); + } + + private TradeableItem fromItemStack(ItemStack itemStack) + { + if (itemStack == null) + { + return null; + } + + for (TradeableItem item : _selling) + { + ItemStack itemStack2 = item.getLootItem().getItemStack(); + + if (itemStack.getType() == itemStack2.getType()) + { + return item; + } + } + + return null; + } + + private ItemStack getConfirm() + { + return new ItemBuilder(Material.EMERALD_BLOCK) + .setTitle(C.cGreenB + "Confirm") + .addLore("", "Click to sell these current items", "at a price of " + F.currency(GlobalCurrency.GEM, _total) + ".") + .build(); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/ShopModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/ShopModule.java new file mode 100644 index 00000000..f647b4e1 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/ShopModule.java @@ -0,0 +1,251 @@ +package mineplex.gemhunters.shop; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.core.google.GoogleSheetsManager; +import mineplex.core.google.SheetObjectDeserialiser; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser; +import mineplex.gemhunters.safezone.SafezoneModule; +import mineplex.gemhunters.shop.deserialisers.VillagerPropertiesDeserialiser; +import mineplex.gemhunters.util.SlackRewardBot; +import mineplex.gemhunters.world.WorldDataModule; +import org.bukkit.Location; +import org.bukkit.entity.Villager; +import org.bukkit.event.EventHandler; + +import java.util.*; + +@ReflectivelyCreateMiniPlugin +public class ShopModule extends MiniPlugin +{ + + private static final String SHEET_FILE_NAME = "GEM_HUNTERS_SHOP"; + private static final String VILLAGER_MASTER_SHEET_NAME = "VILLAGER_MASTER"; + private static final VillagerPropertiesDeserialiser VILLAGER_PROPERTIES_DESERIALISER = new VillagerPropertiesDeserialiser(); + private static final LootItemDeserialiser DESERIALISER = new LootItemDeserialiser(); + private static final SheetObjectDeserialiser COST_DESERIALISER = values -> Integer.parseInt(values[10]); + + private static final int MINIMUM_ITEMS = 1; + private static final int MAXIMUM_ITEMS = 5; + + private static final String[] NAMES = { + "Andrew", "Jon", "Bob", "Sam", "Ronan", "Alex", "Joe", "Emma", "Giovani", "Dean", "Josh", "Geoffrey", "Parker", "Spencer", "Luke", "Peter", "William", "Connor" + }; + + private final GoogleSheetsManager _sheets; + private final SafezoneModule _safezone; + private final WorldDataModule _worldData; + + private final Map> _trades; + private final Map _properties; + + private final List _npcs; + private final Map> _spawnedIndexes; + + private ShopModule() + { + super("Shop"); + + _sheets = require(GoogleSheetsManager.class); + _safezone = require(SafezoneModule.class); + _worldData = require(WorldDataModule.class); + + _trades = new HashMap<>(); + _properties = new HashMap<>(); + + _npcs = new ArrayList<>(); + _spawnedIndexes = new HashMap<>(); + + runSyncLater(this::updateVillagerTrades, 20); + } + + public void updateVillagerTrades() + { + log("Updating villager trades"); + Map>> map = _sheets.getSheetData(SHEET_FILE_NAME); + + for (String key : map.keySet()) + { + //TODO this is super temporary + if (key.equals("PINK")) + { + continue; + } + + if (key.equals(VILLAGER_MASTER_SHEET_NAME)) + { + int row = 0; + + for (List rows : map.get(key)) + { + row++; + try + { + VillagerProperties properties = VILLAGER_PROPERTIES_DESERIALISER.deserialise(rows.toArray(new String[0])); + _properties.put(properties.getDataKey(), properties); + } + catch (Exception e) + { + } + } + continue; + } + + Set items = new HashSet<>(); + int row = 0; + + for (List rows : map.get(key)) + { + row++; + try + { + String[] values = rows.toArray(new String[0]); + items.add(new TradeableItem(DESERIALISER.deserialise(values), COST_DESERIALISER.deserialise(values))); + } + catch (Exception e) + { + } + } + + _trades.put(key, items); + } + + log("Finished updating villager trades"); + } + + @EventHandler + public void updateSpawnedVillagers(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + Iterator iterator = _npcs.iterator(); + + while (iterator.hasNext()) + { + TraderNPC npc = iterator.next(); + int expireTime = npc.getProperties().getExpireRate(); + + if (expireTime > 0 && UtilTime.elapsed(npc.getSpawnedAt(), expireTime)) + { + npc.getEntity().remove(); + iterator.remove(); + } + } + + for (String key : _properties.keySet()) + { + List locations = _worldData.getSpawnLocation(capitalise(key)); + VillagerProperties properties = _properties.get(key); + + if (!UtilTime.elapsed(properties.getLastSpawn(), properties.getSpawnRate())) + { + continue; + } + + properties.setLastSpawn(); + + // Only spawn more chests if we need to + int max = properties.getMax(); + int spawned = 0; + + for (TraderNPC npc : _npcs) + { + if (npc.getProperties().getDataKey().equals(key)) + { + spawned++; + } + } + + // If there are too many chests of this type we can ignore it + if (spawned > max) + { + continue; + } + + Set usedIndexes = _spawnedIndexes.get(key); + + if (usedIndexes == null) + { + _spawnedIndexes.put(key, new HashSet<>()); + usedIndexes = _spawnedIndexes.get(key); + } + + if (locations.size() == usedIndexes.size()) + { + continue; + } + + int index = getFreeIndex(locations.size(), usedIndexes); + + if (index == -1) + { + return; + } + + Location randomLocation = locations.get(index); + + randomLocation.setYaw(UtilMath.r(360)); + + usedIndexes.add(index); + + String name = NAMES[UtilMath.r(NAMES.length)]; + + name = (properties.isSelling() ? C.cGold + "Buy" : C.cGreen + "Sell") + C.cGray + " - " + C.cWhite + name; + + //DebugModule.getInstance().d("Trader at " + UtilWorld.locToStrClean(randomLocation) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max); + if (properties.isSelling()) + { + _npcs.add(new TraderNPC(_plugin, randomLocation, Villager.class, name, _safezone.isInSafeZone(randomLocation), properties, getRandomItemSet(_trades.get(key)))); + } + else + { + new SellingNPC(_plugin, randomLocation, Villager.class, name, _safezone.isInSafeZone(randomLocation), _trades.get(key)); + } + } + } + + private int getFreeIndex(int endIndex, Set used) + { + int index = -1; + + while (index == -1 || used.contains(index)) + { + index = UtilMath.r(endIndex); + } + + used.add(index); + + return index; + } + + private Set getRandomItemSet(Set items) + { + int size = UtilMath.rRange(MINIMUM_ITEMS, MAXIMUM_ITEMS); + Set items2 = new HashSet<>(size); + + for (int i = 0; i < size; i++) + { + items2.add(UtilAlg.Random(items)); + } + + return items2; + } + + private String capitalise(String s) + { + String right = s.toLowerCase().substring(1); + char left = Character.toUpperCase(s.charAt(0)); + + return left + right; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TradeableItem.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TradeableItem.java new file mode 100644 index 00000000..a43ab565 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TradeableItem.java @@ -0,0 +1,27 @@ +package mineplex.gemhunters.shop; + +import mineplex.gemhunters.loot.LootItem; + +public class TradeableItem +{ + + private final LootItem _item; + private final int _cost; + + public TradeableItem(LootItem item, int cost) + { + _item = item; + _cost = cost; + } + + public LootItem getLootItem() + { + return _item; + } + + public int getCost() + { + return _cost; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java new file mode 100644 index 00000000..dbd7c166 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java @@ -0,0 +1,158 @@ +package mineplex.gemhunters.shop; + +import java.util.List; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.util.SimpleNPC; + +public class TraderNPC extends SimpleNPC +{ + private final EconomyModule _economy; + + private final VillagerProperties _properties; + private final Set _selling; + private final Inventory _inv; + + private final long _spawnedAt; + + public TraderNPC(JavaPlugin plugin, Location spawn, Class type, String name, boolean vegetated, VillagerProperties properties, Set selling) + { + super(plugin, spawn, type, name, null, vegetated); + + _economy = Managers.require(EconomyModule.class); + + _properties = properties; + _selling = selling; + _inv = plugin.getServer().createInventory(null, 9, name); + _spawnedAt = System.currentTimeMillis(); + + int index = 1; + + for (TradeableItem item : _selling) + { + ItemStack itemStack = new ItemBuilder(item.getLootItem().getItemStack()).addLore("Cost: " + F.currency(GlobalCurrency.GEM, item.getCost())).build(); + + _inv.setItem(index++, itemStack); + } + } + + @Override + @EventHandler + public void npcClick(PlayerInteractEntityEvent event) + { + super.npcClick(event); + + if (event.getRightClicked().equals(_entity)) + { + event.setCancelled(true); + event.getPlayer().openInventory(_inv); + } + } + + @EventHandler + public void inventoryClick(InventoryClickEvent event) + { + if (event.getInventory() == null) + { + return; + } + + if (!event.getInventory().equals(_inv)) + { + return; + } + + event.setCancelled(true); + + ItemStack itemStack = event.getCurrentItem(); + + if (itemStack == null) + { + return; + } + + Player player = (Player) event.getWhoClicked(); + int gems = _economy.getGems(player); + int cost = fromItemStack(itemStack); + + if (cost == 0) + { + return; + } + + if (cost > gems) + { + player.sendMessage(F.main("Shop", "I'm sorry you don't have enough gems to purchase this.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F); + return; + } + + if (!UtilInv.HasSpace(player, itemStack.getType(), itemStack.getAmount())) + { + player.sendMessage(F.main("Shop", "I'm sorry you don't have enough space to hold that.")); + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F); + return; + } + + _economy.removeFromStore(player, cost); + + // Remove cost lore + ItemBuilder builder = new ItemBuilder(itemStack); + + List lore = builder.getLore(); + lore.remove(lore.size() - 1); + builder.setLore(lore.toArray(new String[0])); + + itemStack = builder.build(); + + String itemName = ItemStackFactory.Instance.GetName(itemStack, true); + + player.sendMessage(F.main("Shop", "Purchased " + F.elem(itemName) + "!")); + player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1.2F); + player.getInventory().addItem(itemStack); + } + + public int fromItemStack(ItemStack itemStack) + { + for (TradeableItem item : _selling) + { + ItemStack itemStack2 = item.getLootItem().getItemStack(); + + if (itemStack.getType() == itemStack2.getType()) + { + return item.getCost(); + } + } + + return 0; + } + + public final VillagerProperties getProperties() + { + return _properties; + } + + public final long getSpawnedAt() + { + return _spawnedAt; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/VillagerProperties.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/VillagerProperties.java new file mode 100644 index 00000000..db5ed349 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/VillagerProperties.java @@ -0,0 +1,66 @@ +package mineplex.gemhunters.shop; + +public class VillagerProperties +{ + + private final String _name; + private final String _dataKey; + private final boolean _selling; + private final int _spawnRate; + private final int _expireRate; + private final int _max; + + private long _lastSpawn; + + public VillagerProperties(String name, String dataKey, boolean selling, int spawnRate, int expireRate, int max) + { + _name = name; + _dataKey = dataKey; + _selling = selling; + _spawnRate = spawnRate; + _expireRate = expireRate; + _max = max; + + setLastSpawn(); + } + + public final String getName() + { + return _name; + } + + public final String getDataKey() + { + return _dataKey; + } + + public boolean isSelling() + { + return _selling; + } + + public final int getSpawnRate() + { + return _spawnRate; + } + + public final int getExpireRate() + { + return _expireRate; + } + + public final int getMax() + { + return _max; + } + + public void setLastSpawn() + { + _lastSpawn = System.currentTimeMillis(); + } + + public long getLastSpawn() + { + return _lastSpawn; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/deserialisers/VillagerPropertiesDeserialiser.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/deserialisers/VillagerPropertiesDeserialiser.java new file mode 100644 index 00000000..b8014ecd --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/deserialisers/VillagerPropertiesDeserialiser.java @@ -0,0 +1,25 @@ +package mineplex.gemhunters.shop.deserialisers; + +import mineplex.core.google.SheetObjectDeserialiser; +import mineplex.gemhunters.shop.VillagerProperties; + +public class VillagerPropertiesDeserialiser implements SheetObjectDeserialiser +{ + + @Override + public VillagerProperties deserialise(String[] values) throws ArrayIndexOutOfBoundsException + { + String name = values[0]; + String dataKey = values[1]; + + boolean selling = values[2].equalsIgnoreCase("Selling"); + + int spawnRate = Integer.parseInt(values[4]); + int expireRate = Integer.parseInt(values[5]); + + int max = Integer.parseInt(values[7]); + + return new VillagerProperties(name, dataKey, selling, spawnRate, expireRate, max); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java new file mode 100644 index 00000000..44dfe74e --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java @@ -0,0 +1,262 @@ +package mineplex.gemhunters.spawn; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.WorldBorder; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.portal.GenericServer; +import mineplex.core.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.core.recharge.Recharge; +import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent; +import mineplex.gemhunters.playerstatus.PlayerStatusModule; +import mineplex.gemhunters.playerstatus.PlayerStatusType; +import mineplex.gemhunters.safezone.SafezoneModule; +import mineplex.gemhunters.spawn.command.HubCommand; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; +import mineplex.gemhunters.util.ColouredTextAnimation; +import mineplex.gemhunters.util.SimpleNPC; +import mineplex.gemhunters.world.WorldDataModule; + +@ReflectivelyCreateMiniPlugin +public class SpawnModule extends MiniPlugin +{ + public enum Perm implements Permission + { + HUB_COMMAND, + } + + public static final int WORLD_BORDER_RADIUS = 1024; + private static final int MAX_SPAWNING_Y = 73; + private static final int MIN_PLAYER_DISTANCE_SQUARED = 6400; + + private final PlayerStatusModule _status; + private final SafezoneModule _safezone; + private final WorldDataModule _worldData; + + private Location _spawn; + private Location _center; + private boolean _npcsSpawned; + + private SpawnModule() + { + super("Spawn"); + + _status = require(PlayerStatusModule.class); + _safezone = require(SafezoneModule.class); + _worldData = require(WorldDataModule.class); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.PLAYER.setPermission(Perm.HUB_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new HubCommand(this)); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerJoin(PlayerJoinEvent event) + { + if (_spawn == null || _center == null) + { + _spawn = _worldData.getCustomLocation("PLAYER_SPAWN").get(0); + _center = new Location(_worldData.World, 0, 64, 0); + _worldData.World.setSpawnLocation(_spawn.getBlockX(), _spawn.getBlockY(), _spawn.getBlockZ()); + } + + if (_npcsSpawned) + { + return; + } + + WorldBorder border = _spawn.getWorld().getWorldBorder(); + + border.setCenter(_spawn); + border.setSize(WORLD_BORDER_RADIUS * 2); + + _npcsSpawned = true; + + { + Location location = _worldData.getCustomLocation("TELEPORT_NPC").get(0); + + location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn))); + + new SimpleNPC(_plugin, location, Villager.class, C.cDRed + "! " + C.cRedB + "Enter The World" + C.cDRed + " !", clicker -> { + + Location toTeleport = getRandomLocation(); + + if (toTeleport == null) + { + clicker.sendMessage(F.main(_moduleName, "A suitable teleport location could not be found. Please try again in a few seconds.")); + return; + } + + PlayerTeleportIntoMapEvent teleportEvent = new PlayerTeleportIntoMapEvent(clicker, toTeleport); + + UtilServer.CallEvent(teleportEvent); + + if (teleportEvent.isCancelled()) + { + clicker.sendMessage(F.main(_moduleName, "Something went wrong there, sorry. Please try again in a few seconds.")); + return; + } + + clicker.teleport(toTeleport); + clicker.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 4 * 20, 9)); + clicker.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 4 * 20, 9)); + + ColouredTextAnimation animation = new ColouredTextAnimation("GEM HUNTERS", C.cGoldB + "M ", C.cGoldB + " M", new String[] { C.cDGreenB, C.cGreenB, C.cWhiteB }); + + runSyncTimer(new BukkitRunnable() + { + + @Override + public void run() + { + if (animation.displayAsTitle(clicker)) + { + cancel(); + } + } + }, 10, 4); + }); + } + { + Location location = _worldData.getCustomLocation("RETURN_TO_HUB").get(0); + + location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn))); + + new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Return To Hub", clicker -> { + + Portal.getInstance().sendPlayerToGenericServer(clicker, GenericServer.HUB, Intent.PLAYER_REQUEST); + + }); + } + { + Location location = _worldData.getCustomLocation("TUTORIAL").get(0); + + location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn))); + + new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Gem Hunters Tutorial", null); + } + { + for (Location location : _worldData.getCustomLocation("RANDOM_TELEPORT")) + { + new SimpleNPC(_plugin, location, Villager.class, C.cYellowB + "Random Teleport", clicker -> + { + + if (_status.Get(clicker).getStatusType() == PlayerStatusType.COMBAT || !Recharge.Instance.usable(clicker, "Cash Out")) + { + clicker.sendMessage(F.main(_moduleName, "You can not do this right now.")); + return; + } + + Location toTeleport = getRandomLocation(); + + if (toTeleport == null) + { + clicker.sendMessage(F.main(_moduleName, "A suitable teleport location could not be found. Please try again in a few seconds.")); + return; + } + + clicker.teleport(toTeleport); + }); + } + } + } + + @EventHandler + public void clearExp(PlayerCustomRespawnEvent event) + { + Player player = event.getPlayer(); + + player.setLevel(0); + player.setExp(0); + } + + + public void teleportToSpawn(Player player) + { + player.teleport(_spawn); + } + + public boolean isSuitable(Block block) + { + Block up = block.getRelative(BlockFace.UP); + Block down = block.getRelative(BlockFace.DOWN); + + if (block.getType() != Material.AIR || down.getType() == Material.AIR || down.getType() == Material.LEAVES || up.getType() == Material.LEAVES || UtilBlock.liquid(down) || UtilBlock.liquid(up) || UtilBlock.liquid(block) || _safezone.isInSafeZone(block.getLocation()) || block.getLocation().getBlockY() > MAX_SPAWNING_Y) + { + return false; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (_safezone.isInSafeZone(player.getLocation())) + { + continue; + } + + if (UtilMath.offsetSquared(player.getLocation(), block.getLocation()) < MIN_PLAYER_DISTANCE_SQUARED) + { + return false; + } + } + + return true; + } + + public Location getRandomLocation() + { + int attempts = 0; + double range = WORLD_BORDER_RADIUS * 0.5; + + while (attempts < 100) + { + Location possible = UtilBlock.getHighest(_worldData.World, UtilAlg.getRandomLocation(_center, range)).getLocation(); + + if (isSuitable(possible.getBlock())) + { + return possible.add(0, 1, 0); + } + + attempts++; + } + + return null; + } + + public Location getCenter() + { + return _center; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/command/HubCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/command/HubCommand.java new file mode 100644 index 00000000..22d0bf68 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/command/HubCommand.java @@ -0,0 +1,23 @@ +package mineplex.gemhunters.spawn.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.portal.GenericServer; +import mineplex.core.portal.Intent; +import mineplex.core.portal.Portal; +import mineplex.gemhunters.spawn.SpawnModule; + +public class HubCommand extends CommandBase +{ + public HubCommand(SpawnModule plugin) + { + super(plugin, SpawnModule.Perm.HUB_COMMAND, "hub", "lobby"); + } + + @Override + public void Execute(Player caller, String[] args) + { + Portal.getInstance().sendPlayerToGenericServer(caller, GenericServer.HUB, Intent.PLAYER_REQUEST); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/event/PlayerTeleportIntoMapEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/event/PlayerTeleportIntoMapEvent.java new file mode 100644 index 00000000..51b6e6d6 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/event/PlayerTeleportIntoMapEvent.java @@ -0,0 +1,56 @@ +package mineplex.gemhunters.spawn.event; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class PlayerTeleportIntoMapEvent extends PlayerEvent implements Cancellable +{ + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean _cancel; + private Location _to; + + public PlayerTeleportIntoMapEvent(Player who, Location to) + { + super(who); + + _to = to; + } + + public void setTo(Location to) + { + _to = to; + } + + public Location getTo() + { + return _to; + } + + 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; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/SupplyDrop.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/SupplyDrop.java new file mode 100644 index 00000000..a8d827ce --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/SupplyDrop.java @@ -0,0 +1,209 @@ +package mineplex.gemhunters.supplydrop; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import mineplex.core.common.util.*; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.FallingBlock; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.BlockVector; + +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.SchematicData; +import mineplex.core.common.block.schematic.UtilSchematic; + +/** + * Represents an instance of a Supply Drop.
+ * A supply drop consists of a helicopter flying through the map from a one + * location to another. Upon reaching it's destination it will drop a loot chest + * which players can then fight over.
+ * The helicopter will then fly away towards a despawning location.
+ *
+ * The helicopter will be made up of a collection of blocks that are moved along + * a linear path. The look of this helicopter is saved in the map and is stored + * in internal memory on startup.
+ *
+ * The blades of the helicopter rotate, this is done within this class.
+ *
+ * {@link SupplyDropModule} handles when and where these supply drops will + * spawn. + */ +public class SupplyDrop +{ + + private static final String SCHEMATIC_PATH = ".." + File.separator + ".." + File.separator + "update" + File.separator + "files" + File.separator + "Helicopter.schematic"; + private static final int BLADE_LENGTH = 7; + + private final String _name; + private Location _destination; + private Location _despawn; + private Location _current; + private Location _blade; + + private final Set _lastHelicopter; + private final Set _bladeBlocks; + private Schematic _schematic; + private boolean _diagonal; + + public SupplyDrop(String name, Location spawn, Location destination, Location despawn) + { + _name = name; + _destination = destination.clone(); + _despawn = despawn.clone(); + _current = spawn.clone().add(-2, 0, 0); + _lastHelicopter = new HashSet<>(100); + _bladeBlocks = new HashSet<>(20); + + try + { + _schematic = UtilSchematic.loadSchematic(new File(SCHEMATIC_PATH)); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + public boolean advancePath() + { + boolean done = moveHelicopter(); + + if (!done) + { + rotateBlades(); + } + + _current.add(0, 0, 1); + + return done; + } + + public boolean moveHelicopter() + { + _current.getChunk().load(); + + for (Block block : _lastHelicopter) + { + block.setType(Material.AIR); + } + + _lastHelicopter.clear(); + + if (_blade != null) + { + if (UtilMath.offset2dSquared(_blade, _despawn) < 4) + { + for (Block block : _bladeBlocks) + { + block.setType(Material.AIR); + } + + return true; + } + } + + SchematicData data = _schematic.paste(_current, true); + + _blade = data.getDataLocationMap().getIronLocations(DyeColor.RED).get(0); + + for (BlockVector vector : data.getBlocks()) + { + Location location = _current.add(vector); + + _lastHelicopter.add(location.getBlock()); + + _current.subtract(vector); + } + + return false; + } + + public void rotateBlades() + { + _diagonal = !_diagonal; + + for (Block block : _bladeBlocks) + { + block.setType(Material.AIR); + } + + _bladeBlocks.clear(); + + if (_diagonal) + { + for (int x = -1; x <= 1; x += 2) + { + for (int z = -1; z <= 1; z += 2) + { + for (Location location : UtilShapes.getLinesLimitedPoints(_blade, _blade.clone().add(x * BLADE_LENGTH, 0, z * BLADE_LENGTH), BLADE_LENGTH)) + { + Block block = location.getBlock(); + + _bladeBlocks.add(block); + block.setType(Material.STEP); + } + } + } + } + else + { + for (int x = -1; x <= 1; x += 2) + { + for (Location location : UtilShapes.getLinesLimitedPoints(_blade, _blade.clone().add(x * BLADE_LENGTH, 0, 0), BLADE_LENGTH)) + { + Block block = location.getBlock(); + + _bladeBlocks.add(block); + block.setType(Material.STEP); + } + } + + for (int z = -1; z <= 1; z += 2) + { + for (Location location : UtilShapes.getLinesLimitedPoints(_blade, _blade.clone().add(0, 0, z * BLADE_LENGTH), BLADE_LENGTH)) + { + Block block = location.getBlock(); + + _bladeBlocks.add(block); + block.setType(Material.STEP); + } + } + } + } + + public void stop() + { + for (Block block : _bladeBlocks) + { + block.setType(Material.AIR); + } + + for (Block block : _lastHelicopter) + { + block.setType(Material.AIR); + } + } + + public final String getName() + { + return _name; + } + + public final Location getCurrentLocation() + { + return _current; + } + + public final Location getChestLocation() + { + return _destination; + } + + public final Location getBladeLocation() { return _blade; } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/SupplyDropModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/SupplyDropModule.java new file mode 100644 index 00000000..33a58bff --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/SupplyDropModule.java @@ -0,0 +1,260 @@ +package mineplex.gemhunters.supplydrop; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.supplydrop.command.SupplyDropCommand; +import mineplex.gemhunters.world.WorldDataModule; + +@ReflectivelyCreateMiniPlugin +public class SupplyDropModule extends MiniPlugin +{ + public enum Perm implements Permission + { + SUPPLY_DROP_COMMAND, + START_SUPPLY_DROP_COMMAND, + STOP_SUPPLY_DROP_COMMAND, + } + + private static final long SEQUENCE_TIMER = TimeUnit.MINUTES.toMillis(20); + + private static final String CHEST_COLOUR = "RED"; + private static final String LOCATION_DATA = "SUPPLY_DROP"; + + private final BlockRestore _blockRestore; + private final LootModule _loot; + private final WorldDataModule _worldData; + + private final Set _beaconBlocks; + + private String[] _locationKeys; + private SupplyDrop _current; + + private long _lastSupplyDrop; + + private SupplyDropModule() + { + super("Supply Drop"); + + _blockRestore = require(BlockRestore.class); + _loot = require(LootModule.class); + _worldData = require(WorldDataModule.class); + + _beaconBlocks = new HashSet<>(); + + _lastSupplyDrop = System.currentTimeMillis(); + + generatePermissions(); + } + + private void generatePermissions() + { + + PermissionGroup.ADMIN.setPermission(Perm.SUPPLY_DROP_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.START_SUPPLY_DROP_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.STOP_SUPPLY_DROP_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new SupplyDropCommand(this)); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + if (isActive()) + { + if (_current.advancePath()) + { + stopSequence(); + } + else if (UtilMath.offset2d(_current.getBladeLocation(), _current.getChestLocation()) < 1) + { + spawnLootChest(); + } + } + else if (UtilTime.elapsed(_lastSupplyDrop, SEQUENCE_TIMER)) + { + startSequence(); + } + } + + @EventHandler + public void itemSpawn(ItemSpawnEvent event) + { + // The Helicopter has a door. This stops it dropping items when it + // moves. + if (event.getEntity().getItemStack().getType() == Material.IRON_DOOR) + { + event.setCancelled(true); + } + } + + public void startSequence(String locationKey) + { + Location spawn = _worldData.getCustomLocation(LOCATION_DATA + " " + locationKey + " Start").get(0); + Location destination = _worldData.getCustomLocation(LOCATION_DATA + " " + locationKey + " Chest").get(0); + Location despawn = _worldData.getCustomLocation(LOCATION_DATA + " " + locationKey + " End").get(0); + + // Construct a beacon + for (Pair> pair : UtilBlock.getBeaconBlocks(destination, (byte) 0)) + { + // Look it's like a maze + _beaconBlocks.add(pair.getLeft().getBlock()); + _blockRestore.add(pair.getLeft().getBlock(), pair.getRight().getLeft().getId(), pair.getRight().getRight(), Long.MAX_VALUE); + } + + // Inform the masses + UtilTextMiddle.display(C.cYellow + locationKey, C.cGray + "A Supply Drop is spawning!", 10, 40, 10); + UtilServer.broadcast(F.main(_moduleName, "A Supply Drop is spawning at " + F.elem(locationKey) + " - " + C.cYellow + UtilWorld.locToStrClean(destination))); + + _lastSupplyDrop = System.currentTimeMillis(); + _current = new SupplyDrop(locationKey, spawn, destination, despawn); + } + + public void startSequence() + { + startSequence(getLocationKeys()[UtilMath.r(getLocationKeys().length)]); + } + + public void stopSequence() + { + // Remove beacon (only needed incase the command was executed) + for (Block block : _beaconBlocks) + { + _blockRestore.restore(block); + } + + _beaconBlocks.clear(); + _current.stop(); + _current = null; + } + + public void spawnLootChest() + { + Location chest = _current.getBladeLocation().clone().subtract(0, 10, 0); + + runSyncTimer(new BukkitRunnable() + { + + Block chestBlock = chest.getBlock(); + + @Override + public void run() + { + chestBlock.setType(Material.AIR); + chestBlock = chestBlock.getRelative(BlockFace.DOWN); + chestBlock.setType(Material.CHEST); + + if (chestBlock.getRelative(BlockFace.DOWN).getType() != Material.AIR) + { + // Add location that the chest will appear at into the spawned + // chests list so that LootModule can populate it with loot. + _loot.addSpawnedChest(chestBlock.getLocation(), CHEST_COLOUR); + + // Remove beacon + for (Block beacon : _beaconBlocks) + { + _blockRestore.restore(beacon); + } + + _beaconBlocks.clear(); + cancel(); + } + + UtilFirework.playFirework(chestBlock.getLocation().add(0.5, 1, 0.5), FireworkEffect.Type.BALL, Color.YELLOW, true, false); + } + }, 0, 5); + } + + public boolean isActive() + { + return _current != null; + } + + public SupplyDrop getActive() + { + return _current; + } + + public long getLastSupplyDrop() + { + return _lastSupplyDrop; + } + + public long getSequenceTimer() + { + return SEQUENCE_TIMER; + } + + public String[] getLocationKeys() + { + if (_locationKeys == null) + { + List supplyDropKeys = new ArrayList<>(); + + for (String key : _worldData.getAllCustomLocations().keySet()) + { + if (key.startsWith(LOCATION_DATA)) + { + String[] split = key.split(" "); + String nameKey = ""; + + for (int i = 1; i < split.length - 1; i++) + { + nameKey += split[i] + " "; + } + + nameKey = nameKey.trim(); + + if (!supplyDropKeys.contains(nameKey)) + { + supplyDropKeys.add(nameKey); + } + } + } + + _locationKeys = supplyDropKeys.toArray(new String[0]); + } + + return _locationKeys; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/EndCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/EndCommand.java new file mode 100644 index 00000000..c3535edb --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/EndCommand.java @@ -0,0 +1,28 @@ +package mineplex.gemhunters.supplydrop.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.F; +import mineplex.gemhunters.supplydrop.SupplyDropModule; + +public class EndCommand extends CommandBase +{ + public EndCommand(SupplyDropModule plugin) + { + super(plugin, SupplyDropModule.Perm.STOP_SUPPLY_DROP_COMMAND, "stop"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (!Plugin.isActive()) + { + caller.sendMessage(F.main(Plugin.getName(), "There is no current supply drop.")); + return; + } + + caller.sendMessage(F.main(Plugin.getName(), "Stopping the current supply drop.")); + Plugin.stopSequence(); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/StartCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/StartCommand.java new file mode 100644 index 00000000..d05ae90f --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/StartCommand.java @@ -0,0 +1,77 @@ +package mineplex.gemhunters.supplydrop.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.gemhunters.supplydrop.SupplyDropModule; + +public class StartCommand extends CommandBase +{ + public StartCommand(SupplyDropModule plugin) + { + super(plugin, SupplyDropModule.Perm.START_SUPPLY_DROP_COMMAND, "start"); + } + + @Override + public void Execute(Player caller, String[] args) + { + boolean override = false; + + if (Plugin.isActive()) + { + for (String arg : args) + { + if (arg.equalsIgnoreCase("-f")) + { + override = true; + caller.sendMessage(F.main(Plugin.getName(), "Overriding the current supply drop. You know best.")); + Plugin.stopSequence(); + break; + } + } + + if (!override) + { + caller.sendMessage(F.main(Plugin.getName(), "Just saying there is another supply drop already running. If you really really want to override the current one. Add " + F.elem("-f") + " as an additional argument.")); + return; + } + } + + if (args.length == 0 || override && args.length == 1) + { + caller.sendMessage(F.main(Plugin.getName(), "Starting the supply drop sequence at one of the random locations.")); + Plugin.startSequence(); + } + else + { + StringBuilder inputBuilder = new StringBuilder(); + + for (int i = 0; i < args.length; i++) + { + inputBuilder.append(args[i]); + inputBuilder.append(" "); + } + + String input = inputBuilder.toString().trim(); + + for (String key : Plugin.getLocationKeys()) + { + if (input.equalsIgnoreCase(key)) + { + caller.sendMessage(F.main(Plugin.getName(), "Starting the supply drop sequence at " + F.elem(key) + ".")); + Plugin.startSequence(key); + return; + } + } + + caller.sendMessage(F.main(Plugin.getName(), "I wasn\'t able to find a location key of the name " + F.elem(input) + ". Possible values:")); + + for (String key : Plugin.getLocationKeys()) + { + caller.sendMessage(C.cGray + "- " + F.elem(key)); + } + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/SupplyDropCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/SupplyDropCommand.java new file mode 100644 index 00000000..32866841 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/supplydrop/command/SupplyDropCommand.java @@ -0,0 +1,27 @@ +package mineplex.gemhunters.supplydrop.command; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.MultiCommandBase; +import mineplex.core.common.util.F; +import mineplex.gemhunters.supplydrop.SupplyDropModule; + +public class SupplyDropCommand extends MultiCommandBase +{ + public SupplyDropCommand(SupplyDropModule plugin) + { + super(plugin, SupplyDropModule.Perm.SUPPLY_DROP_COMMAND, "supplydrop", "supply", "sd"); + + AddCommand(new StartCommand(plugin)); + AddCommand(new EndCommand(plugin)); + } + + @Override + protected void Help(Player caller, String[] args) + { + caller.sendMessage(F.main(Plugin.getName(), "Command List:")); + caller.sendMessage(F.help("/" + _aliasUsed + " start [location]", "Starts the supply drop sequence at a certain location. Leaving [location] blank picks a random one.", ChatColor.DARK_RED)); + caller.sendMessage(F.help("/" + _aliasUsed + " stop", "Stops the current supply drop.", ChatColor.DARK_RED)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/tutorial/GemHuntersTutorial.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/tutorial/GemHuntersTutorial.java new file mode 100644 index 00000000..16acd508 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/tutorial/GemHuntersTutorial.java @@ -0,0 +1,128 @@ +package mineplex.gemhunters.tutorial; + +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import mineplex.core.Managers; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.texttutorial.tutorial.Phase; +import mineplex.core.texttutorial.tutorial.Tutorial; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.spawn.SpawnModule; +import mineplex.gemhunters.world.WorldDataModule; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class GemHuntersTutorial extends Tutorial implements Listener +{ + + private final SpawnModule _spawn; + private final WorldDataModule _worldData; + + private final int[][] _locations = { + { + 92, 69, 148, 53, 15 + }, + { + -125, 76, 94, 90, 0 + }, + { + -220, 69, -280, -135, 20 + }, + { + -611, 78, -19, -135, 20 + }, + { + -454, 68, 231, 0, 0 + }, + { + 300, 88, 45, 125, 0 + } + }; + + public GemHuntersTutorial() + { + super("Gem Hunters", "gemhunterstutorial", 0); + + _spawn = Managers.require(SpawnModule.class); + _worldData = Managers.require(WorldDataModule.class); + + addPhase(new Phase(getLocation(0), "Welcome", new String[] { + "Welcome To " + C.cGreen + "Gem Hunters", + })); + addPhase(new Phase(getLocation(1), "PVP", new String[] { + "Players start with " + C.cGreen + EconomyModule.GEM_START_COST + C.cWhite + " Gems and must survive in the city.", + "Killing another player will gift you " + C.cYellow + "50%" + C.cWhite + " of their total gems.", + })); + addPhase(new Phase(getLocation(2), "Safezones", new String[] { + "In Safe Zones you cannot take damage and can purchase items like", + "Food, Weapons, and Gear with the Gems you earn in the world.", + })); + addPhase(new Phase(getLocation(3), "Items", new String[] { + "Collect items from chests and powerup.", + "You can find anything from Weapons to Cosmetics.", + "If you find something you want to keep you can", + C.cGreen + "Cash Out" + C.cWhite + " at any time by right clicking the " + C.cGreen + "Emerald" + C.cWhite + " in your inventory.", + })); + addPhase(new Phase(getLocation(4), "Cashing Out", new String[] { + "Cashing out will reset your progress in the world,", + "adds any special items you had like", + "Gems, Treasure Shards, Cosmetics or Rank Upgrades to your account!", + })); + addPhase(new Phase(getLocation(5), "Good luck", new String[] { + "Stay safe! Anarchy rules in the world of " + C.cGreen + "Gem Hunters" + C.cWhite + "!" + })); + + UtilServer.RegisterEvents(this); + } + + @Override + public void startTutorial(Player player) + { + super.startTutorial(player); + + player.setAllowFlight(true); + player.setFlying(true); + } + + @Override + public void stopTutorial(Player player) + { + super.stopTutorial(player); + + player.setFlying(false); + player.setAllowFlight(false); + + UtilServer.runSyncLater(() -> _spawn.teleportToSpawn(player), 10); + } + + private Location getLocation(int phase) + { + int[] locations = _locations[phase]; + + return new Location(_worldData.World, locations[0] + 0.5, locations[1] + 0.5, locations[2] + 0.5, locations[3], locations[4]); + } + + @EventHandler + public void updateFlight(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (isInTutorial(player) && !player.isFlying()) + { + player.setAllowFlight(true); + player.setFlying(true); + } + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/ColouredTextAnimation.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/ColouredTextAnimation.java new file mode 100644 index 00000000..fc7dbee7 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/ColouredTextAnimation.java @@ -0,0 +1,123 @@ +package mineplex.gemhunters.util; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilTextMiddle; + +public class ColouredTextAnimation +{ + + private final String _text; + private final String _prefix; + private final String _suffix; + private final String[] _colours; + + private final double _colourChange; + private final double _colourRequirement; + + // Stage 0 + private int _lastIndex; + private double _colour; + private int _colourIndex; + + // Stage 1 + private int _iterations; + + // Stage 2 + private int _colourStage; + + private String _last; + + private int _stage; + + public ColouredTextAnimation(String text, String... colours) + { + this(text, null, null, colours); + } + + public ColouredTextAnimation(String text, String prefix, String suffix, String[] colours) + { + _text = text; + _prefix = prefix; + _suffix = suffix; + _colours = colours; + + _colourChange = (double) 1 / text.length() * 2; + _colourRequirement = (double) 1 / colours.length; + + _lastIndex = text.length() / 2; + _colour = 0; + _colourIndex = 0; + + _iterations = 0; + + _colourStage = 0; + + _stage = 0; + } + + public boolean displayAsTitle(Player... players) + { + String text = next(); + + UtilTextMiddle.display(text, null, 0, 20, 20, players); + + return _stage == -1; + } + + private String next() + { + String display = ""; + + switch (_stage) + { + case 0: + String text = _text.substring(_lastIndex, _text.length() - _lastIndex); + String colour = _colours[_colourIndex]; + + if (_colour >= _colourRequirement * (_colourIndex + 1)) + { + _colourIndex++; + } + + _colour += _colourChange; + _lastIndex--; + + if (_lastIndex == -1) + { + _stage++; + } + + display = colour + text; + break; + case 1: + _iterations++; + + if (_iterations > 4) + { + _stage++; + } + + display = _last; + break; + case 2: + _colourStage++; + + if (_colourStage > 10) + { + // Stop the cycle + _stage = -1; + } + + display = _colours[_colourStage % _colours.length] + ChatColor.stripColor(_last); + break; + default: + break; + } + + _last = display; + return _prefix + display + _suffix; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java new file mode 100644 index 00000000..5e265998 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java @@ -0,0 +1,92 @@ +package mineplex.gemhunters.util; + +import java.util.function.Consumer; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.UtilEnt; + +public class SimpleNPC implements Listener +{ + + protected final LivingEntity _entity; + private final Consumer _clickEvent; + private final boolean _vegetated; + + public SimpleNPC(JavaPlugin plugin, Location spawn, Class type, String name, Consumer clickEvent) + { + this(plugin, spawn, type, name, clickEvent, true); + } + + public SimpleNPC(JavaPlugin plugin, Location spawn, Class type, String name, Consumer clickEvent, boolean vegetated) + { + spawn.getWorld().loadChunk(spawn.getChunk()); + _entity = spawn.getWorld().spawn(spawn, type); + + _entity.setRemoveWhenFarAway(false); + _entity.setCustomName(name); + _entity.setCustomNameVisible(true); + + UtilEnt.vegetate(_entity, true); + UtilEnt.ghost(_entity, true, false); + UtilEnt.setFakeHead(_entity, true); + + _clickEvent = clickEvent; + _vegetated = vegetated; + + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void npcClick(PlayerInteractEntityEvent event) + { + if (!event.getRightClicked().equals(_entity)) + { + return; + } + + event.setCancelled(true); + + if (_clickEvent != null) + { + _clickEvent.accept(event.getPlayer()); + } + } + + @EventHandler + public void npcDamage(EntityDamageEvent event) + { + if (!event.getEntity().equals(_entity) || !_vegetated) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void npcDeath(EntityDeathEvent event) + { + if (!event.getEntity().equals(_entity) || !_vegetated) + { + return; + } + + HandlerList.unregisterAll(this); + } + + public final LivingEntity getEntity() + { + return _entity; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SlackRewardBot.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SlackRewardBot.java new file mode 100644 index 00000000..0bc203be --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SlackRewardBot.java @@ -0,0 +1,47 @@ +package mineplex.gemhunters.util; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilServer; +import mineplex.core.monitor.LagMeter; +import mineplex.core.slack.SlackAPI; +import mineplex.core.slack.SlackMessage; +import mineplex.core.slack.SlackTeam; +import mineplex.gemhunters.loot.rewards.LootItemReward; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.net.MalformedURLException; +import java.net.URL; +import java.text.DecimalFormat; + +public class SlackRewardBot +{ + + private static final DecimalFormat FORMAT = new DecimalFormat("0.0"); + private static final String SLACK_CHANNEL_NAME = "#gem-hunters-logging"; + private static final String SLACK_USERNAME = "Gem Hunters"; + private static final String SLACK_ICON = "http://moppletop.github.io/mineplex/chest-image.png"; + + private static LagMeter _lag; + + public static void logReward(Player player, LootItemReward reward, String status) + { + if (_lag == null) + { + _lag = Managers.get(LagMeter.class); + } + + try + { + SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, SLACK_CHANNEL_NAME, new SlackMessage(SLACK_USERNAME, new URL(SLACK_ICON), + "Rewarding a " + reward.getClass().getSimpleName() + + "\nName: " + ChatColor.stripColor(reward.getItemStack().getItemMeta().getDisplayName()) + + "\nPlayer: " + player.getName() + + "\nStatus: *" + status + "*" + + "\nServer: " + UtilServer.getServerName() + " " + UtilServer.getRegion().toString() + + "\nTPS: " + FORMAT.format(_lag.getTicksPerSecond())), + true); + } + catch (MalformedURLException e) {} + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/Leaderboards.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/Leaderboards.java new file mode 100644 index 00000000..a97b9bef --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/Leaderboards.java @@ -0,0 +1,62 @@ +package mineplex.gemhunters.world; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilServer; +import mineplex.core.leaderboard.Leaderboard; +import mineplex.core.leaderboard.LeaderboardManager; +import mineplex.core.leaderboard.LeaderboardRepository.LeaderboardSQLType; +import mineplex.core.leaderboard.StaticLeaderboard; + +public class Leaderboards +{ + + private static final String STAT_BASE = "Gem Hunters"; + + private final LeaderboardManager _manager; + private final WorldDataModule _worldData; + + public Leaderboards() + { + _manager = Managers.require(LeaderboardManager.class); + _worldData = Managers.require(WorldDataModule.class); + + // Make sure the world is loaded + UtilServer.runSyncLater(this::createLeaderboards, 20); + } + + private void createLeaderboards() + { + _manager.registerLeaderboard("TOP_GEM_HUNTERS_KILLS", new StaticLeaderboard( + _manager, + "Top Kills", + new Leaderboard( + LeaderboardSQLType.ALL, + STAT_BASE + ".Kills" + ), + _worldData.getCustomLocation("TOP_KILLS").get(0))); + _manager.registerLeaderboard("TOP_GEM_HUNTERS_DAILY_KILLS", new StaticLeaderboard( + _manager, + "Top Daily Kills", + new Leaderboard( + LeaderboardSQLType.DAILY, + STAT_BASE + ".Kills" + ), + _worldData.getCustomLocation("TOP_DAILY_KILLS").get(0))); + _manager.registerLeaderboard("TOP_GEM_HUNTERS_GEMS", new StaticLeaderboard( + _manager, + "Top Gems Cashed Out", + new Leaderboard( + LeaderboardSQLType.ALL, + STAT_BASE + ".GemsEarned" + ), + _worldData.getCustomLocation("TOP_GEMS").get(0))); + _manager.registerLeaderboard("TOP_GEM_HUNTERS_DAILY_GEMS", new StaticLeaderboard( + _manager, + "Top Daily Gems Cashed Out", + new Leaderboard( + LeaderboardSQLType.DAILY, + STAT_BASE + ".GemsEarned" + ), + _worldData.getCustomLocation("TOP_DAILY_GEMS").get(0))); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java new file mode 100644 index 00000000..33574a55 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java @@ -0,0 +1,61 @@ +package mineplex.gemhunters.world; + +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class TimeCycle implements Listener +{ + private static final int TICKS_DAY = 1; + private static final int TICKS_NIGHT = 2; + + private final WorldDataModule _worldData; + private World _world; + + private boolean _night; + + public TimeCycle(JavaPlugin plugin) + { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + + _worldData = Managers.get(WorldDataModule.class); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_world == null) + { + _world = _worldData.World; + return; + } + + if (!_night && _world.getTime() > 12000) + { + _night = true; + } + + if (_world.getTime() >= 23900) + { + _world.setTime(0); + _night = false; + } + + _world.setTime(_world.getTime() + (isNight() ? TICKS_NIGHT : TICKS_DAY)); + } + + public boolean isNight() + { + return _world.getTime() > 12000; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/UndergroundMobs.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/UndergroundMobs.java new file mode 100644 index 00000000..4430de95 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/UndergroundMobs.java @@ -0,0 +1,97 @@ +package mineplex.gemhunters.world; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class UndergroundMobs implements Listener +{ + private static final int MAX_MOBS = 400; + private static final String SEWER_KEY = "SEWER_MOB"; + private static final String SUBWAY_KEY = "SUBWAY_MOBS"; + + private final WorldDataModule _worldData; + + private final World _world; + private final Set _entities; + + public UndergroundMobs(JavaPlugin plugin) + { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + + _worldData = Managers.require(WorldDataModule.class); + + _world = _worldData.World; + _entities = new HashSet<>(); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC_20) + { + return; + } + + Iterator iterator = _entities.iterator(); + + while (iterator.hasNext()) + { + Entity entity = iterator.next(); + + if (entity.isDead() || !entity.isValid()) + { + entity.remove(); + iterator.remove(); + } + } + + for (int i = 0; i < 10; i++) + { + if (_entities.size() >= MAX_MOBS) + { + break; + } + + { + Location location = UtilAlg.Random(_worldData.getCustomLocation(SEWER_KEY)).clone().add(0, 1, 0); + Class clazz = UtilMath.random.nextBoolean() ? Zombie.class : Skeleton.class; + Entity entity = _world.spawn(location, clazz); + _entities.add(entity); + } + { + Location location = UtilAlg.Random(_worldData.getCustomLocation(SUBWAY_KEY)).clone().add(0, 1, 0); + Class clazz = Spider.class; + Entity entity = _world.spawn(location, clazz); + _entities.add(entity); + } + } + } + + @EventHandler + public void cancelSuffication(EntityDamageEvent event) + { + if (event.getCause() == DamageCause.SUFFOCATION && _entities.contains(event.getEntity())) + { + event.setCancelled(true); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/WorldDataModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/WorldDataModule.java new file mode 100644 index 00000000..cbcd453f --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/WorldDataModule.java @@ -0,0 +1,303 @@ +package mineplex.gemhunters.world; + +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Difficulty; +import org.bukkit.Location; +import org.bukkit.World; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.timing.TimingManager; + +@ReflectivelyCreateMiniPlugin +public class WorldDataModule extends MiniPlugin +{ + public World World; + public int MinX = 0; + public int MinZ = 0; + public int MaxX = 0; + public int MaxZ = 0; + + public int MinY = -1; + public int MaxY = 256; + + private final Map> SPAWN_LOCATIONS = new LinkedHashMap<>(); + private final Map> DATA_LOCATIONS = new LinkedHashMap<>(); + private final Map> CUSTOM_LOCAITONS = new LinkedHashMap<>(); + + private WorldDataModule() + { + super("World Data"); + + initialize(); + } + + public void initialize() + { + final WorldDataModule worldData = this; + + World = Bukkit.getWorlds().get(0); + + World.setDifficulty(Difficulty.EASY); + World.setGameRuleValue("showDeathMessages", "false"); + + TimingManager.start("WorldData loading WorldConfig."); + worldData.loadWorldConfig(); + TimingManager.stop("WorldData loading WorldConfig."); + } + + public String getFolder() + { + return "world"; + } + + public void loadWorldConfig() + { + // Load Track Data + String line = null; + + try + { + FileInputStream fstream = new FileInputStream(getFolder() + File.separator + "WorldConfig.dat"); + DataInputStream in = new DataInputStream(fstream); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + + List currentTeam = null; + List currentData = null; + + int currentDirection = 0; + + while ((line = br.readLine()) != null) + { + String[] tokens = line.split(":"); + + if (tokens.length < 2) + { + continue; + } + + String key = tokens[0]; + String value = tokens[1]; + + if (key.length() == 0) + { + continue; + } + + // Spawn Locations + if (key.equalsIgnoreCase("TEAM_NAME")) + { + SPAWN_LOCATIONS.put(value, new ArrayList()); + currentTeam = SPAWN_LOCATIONS.get(value); + currentDirection = 0; + } + else if (key.equalsIgnoreCase("TEAM_DIRECTION")) + { + currentDirection = Integer.parseInt(value); + } + else if (key.equalsIgnoreCase("TEAM_SPAWNS")) + { + for (int i = 1; i < tokens.length; i++) + { + Location loc = stringToLocation(tokens[i]); + if (loc == null) + { + continue; + } + + loc.setYaw(currentDirection); + + currentTeam.add(loc); + } + } + + // Data Locations + else if (key.equalsIgnoreCase("DATA_NAME")) + { + DATA_LOCATIONS.put(value, new ArrayList()); + currentData = DATA_LOCATIONS.get(value); + } + else if (key.equalsIgnoreCase("DATA_LOCS")) + { + for (int i = 1; i < tokens.length; i++) + { + Location loc = stringToLocation(tokens[i]); + if (loc == null) + { + continue; + } + + currentData.add(loc); + } + } + + // Custom Locations + else if (key.equalsIgnoreCase("CUSTOM_NAME")) + { + CUSTOM_LOCAITONS.put(value, new ArrayList()); + currentData = CUSTOM_LOCAITONS.get(value); + } + else if (key.equalsIgnoreCase("CUSTOM_LOCS")) + { + for (int i = 1; i < tokens.length; i++) + { + Location loc = stringToLocation(tokens[i]); + if (loc == null) + { + continue; + } + + currentData.add(loc); + } + } + + // Map Bounds + else if (key.equalsIgnoreCase("MIN_X")) + { + try + { + MinX = Integer.parseInt(value); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MinX [" + value + "]"); + } + + } + else if (key.equalsIgnoreCase("MAX_X")) + { + try + { + MaxX = Integer.parseInt(value); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MaxX [" + value + "]"); + } + } + else if (key.equalsIgnoreCase("MIN_Z")) + { + try + { + MinZ = Integer.parseInt(value); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MinZ [" + value + "]"); + } + } + else if (key.equalsIgnoreCase("MAX_Z")) + { + try + { + MaxZ = Integer.parseInt(value); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MaxZ [" + value + "]"); + } + } + else if (key.equalsIgnoreCase("MIN_Y")) + { + try + { + MinY = Integer.parseInt(value); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MinY [" + value + "]"); + } + } + else if (key.equalsIgnoreCase("MAX_Y")) + { + try + { + MaxY = Integer.parseInt(value); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid MaxY [" + value + "]"); + } + } + } + + in.close(); + } + catch (Exception e) + { + e.printStackTrace(); + System.err.println("Line: " + line); + } + } + + private Location stringToLocation(String loc) + { + String[] coords = loc.split(","); + + try + { + return new Location(World, Integer.valueOf(coords[0]) + 0.5, Integer.valueOf(coords[1]), Integer.valueOf(coords[2]) + 0.5); + } + catch (Exception e) + { + System.out.println("World Data Read Error: Invalid Location String [" + loc + "]"); + } + + return null; + } + + public List getSpawnLocation(String colour) + { + if (!SPAWN_LOCATIONS.containsKey(colour)) + { + return new ArrayList(); + } + + return SPAWN_LOCATIONS.get(colour); + } + + public List getDataLocation(String colour) + { + if (!DATA_LOCATIONS.containsKey(colour)) + { + return new ArrayList(); + } + + return DATA_LOCATIONS.get(colour); + } + + public List getCustomLocation(String id) + { + if (!CUSTOM_LOCAITONS.containsKey(id)) + { + return new ArrayList(); + } + + return CUSTOM_LOCAITONS.get(id); + } + + public Map> getAllSpawnLocations() + { + return SPAWN_LOCATIONS; + } + + public Map> getAllCustomLocations() + { + return CUSTOM_LOCAITONS; + } + + public Map> getAllDataLocations() + { + return DATA_LOCATIONS; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/WorldListeners.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/WorldListeners.java new file mode 100644 index 00000000..6d9612c9 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/world/WorldListeners.java @@ -0,0 +1,259 @@ +package mineplex.gemhunters.world; + +import java.io.File; +import java.util.UUID; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockExpEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.LeavesDecayEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilWorld; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class WorldListeners implements Listener +{ + private final JavaPlugin _plugin; + + public WorldListeners(JavaPlugin plugin) + { + _plugin = plugin; + + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void deletePlayerData(PlayerQuitEvent event) + { + _plugin.getServer().getScheduler().runTaskLater(_plugin, () -> + { + World world = event.getPlayer().getWorld(); + UUID uuid = event.getPlayer().getUniqueId(); + String path = world.getWorldFolder().getPath(); + new File(path + File.separator + "playerdata" + File.separator + uuid + ".dat").delete(); + new File(path + File.separator + "stats" + File.separator + uuid + ".json").delete(); + }, 10); + } + + @EventHandler + public void customDamage(CustomDamageEvent event) + { + event.SetDamageToLevel(false); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void blockBreak(BlockBreakEvent event) + { + if (shouldBlock(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void blockPlace(BlockPlaceEvent event) + { + if (event.getBlockPlaced().getType() != Material.CAKE_BLOCK && event.getItemInHand() != null && event.getItemInHand().getType() != Material.FLINT_AND_STEEL && shouldBlock(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void armorStandEdit(PlayerArmorStandManipulateEvent event) + { + if (shouldBlock(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void entityDestory(PlayerInteractAtEntityEvent event) + { + if (shouldBlock(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void entityDamage(EntityDamageEvent event) + { + if (event.getEntity() instanceof ArmorStand || event.getEntity() instanceof ItemFrame) + { + event.setCancelled(true); + } + } + + @EventHandler + public void paintings(HangingBreakEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void itemFrames(PlayerInteractEntityEvent event) + { + if (event.getRightClicked() instanceof ItemFrame) + { + event.setCancelled(true); + } + } + + @EventHandler + public void interact(PlayerInteractEvent event) + { + if (UtilPlayer.isSpectator(event.getPlayer())) + { + event.setCancelled(true); + } + + Block block = event.getClickedBlock(); + + if (block == null) + { + return; + } + + Material material = block.getType(); + + if (material == Material.BEACON || material == Material.DISPENSER || material == Material.HOPPER || material == Material.BREWING_STAND || material == Material.DROPPER) + { + event.setCancelled(true); + } + } + + @EventHandler + public void chunkUnload(ChunkUnloadEvent event) + { + if (!UtilWorld.inWorldBorder(new Location(event.getWorld(), event.getChunk().getX(), 0, event.getChunk().getZ()))) + { + return; + } + + if (event.getChunk().getEntities().length == 0) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void fireSpread(BlockIgniteEvent event) + { + if (event.getCause() == IgniteCause.FLINT_AND_STEEL) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void fireSpread(BlockBurnEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void blockDecay(BlockFadeEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void leavesDecay(LeavesDecayEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void hungerChange(FoodLevelChangeEvent event) + { + Player player = (Player) event.getEntity(); + + // Some witchcraft from the arcade, seems to make hunger not ridiculous. + player.setSaturation(3.8F); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void weather(WeatherChangeEvent event) + { + if (event.toWeatherState()) + { + event.setCancelled(true); + } + } + + @EventHandler + public void bucketEmpty(PlayerBucketEmptyEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void fishingExpRemove(PlayerFishEvent event) + { + event.setExpToDrop(0); + } + + @EventHandler + public void smelt(BlockExpEvent event) + { + Material material = event.getBlock().getType(); + + if (material == Material.FURNACE || material == Material.BURNING_FURNACE) + { + event.setExpToDrop(0); + } + } + + @EventHandler + public void removeExp(EntityDeathEvent event) + { + event.setDroppedExp(0); + } + + @EventHandler + public void removeExp(PlayerFishEvent event) + { + event.setExpToDrop(0); + } + + public boolean shouldBlock(Player player) + { + return player.getGameMode() != GameMode.CREATIVE; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEvent.java new file mode 100644 index 00000000..3113e202 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEvent.java @@ -0,0 +1,179 @@ +package mineplex.gemhunters.worldevent; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import mineplex.core.Managers; +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.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.world.WorldDataModule; +import mineplex.minecraft.game.core.damage.DamageManager; + +public abstract class WorldEvent implements Listener +{ + + private final WorldEventType _eventType; + + private WorldEventState _eventState; + + protected final DamageManager _damage; + protected final LootModule _loot; + protected final WorldDataModule _worldData; + protected final WorldEventModule _worldEvent; + + protected final Set _entities; + + protected long _start; + private long _complete; + + public WorldEvent(WorldEventType eventType) + { + _eventType = eventType; + _eventState = null; + + _damage = Managers.get(DamageManager.class); + _loot = Managers.get(LootModule.class); + _worldData = Managers.get(WorldDataModule.class); + _worldEvent = Managers.get(WorldEventModule.class); + + _entities = new HashSet<>(); + + _worldEvent.registerEvents(this); + } + + public abstract void onStart(); + + public abstract boolean checkToEnd(); + + public abstract void onEnd(); + + public abstract Location[] getEventLocations(); + + public abstract double getProgress(); + + private final void start() + { + if (isLive()) + { + return; + } + + UtilTextMiddle.display(C.cRed + _eventType.getName(), C.cGray + "World Event is starting!", 20, 60, 20); + UtilServer.broadcast(F.main(_worldEvent.getName(), "The " + F.elem(_eventType.getName()) + " world event is starting!")); + + _start = System.currentTimeMillis(); + onStart(); + } + + private final void end() + { + _complete = System.currentTimeMillis(); + + UtilServer.broadcast(F.main(_worldEvent.getName(), "The " + F.elem(_eventType.getName()) + " world event is over!")); + + for (LivingEntity entity : _entities) + { + entity.remove(); + } + + _entities.clear(); + + onEnd(); + } + + @EventHandler + public void updateEntities(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + Iterator iterator = _entities.iterator(); + + while (iterator.hasNext()) + { + Entity entity = iterator.next(); + + if (entity.isDead() || !entity.isValid()) + { + entity.remove(); + iterator.remove(); + } + } + } + + public void addEntity(LivingEntity entity) + { + _entities.add(entity); + } + + public WorldEventType getEventType() + { + return _eventType; + } + + public void setEventState(WorldEventState eventState) + { + _eventState = eventState; + + if (eventState == null) + { + return; + } + + switch (eventState) + { + case WARMUP: + start(); + break; + case COMPLETE: + end(); + break; + default: + break; + } + } + + public boolean isEnabled() + { + return _eventState != null; + } + + public boolean isWarmup() + { + return _eventState == WorldEventState.WARMUP; + } + + public boolean isLive() + { + return _eventState == WorldEventState.LIVE; + } + + public boolean isInProgress() + { + return isWarmup() || isLive(); + } + + public WorldEventState getEventState() + { + return _eventState; + } + + public long getCompleteTime() + { + return _complete; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventModule.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventModule.java new file mode 100644 index 00000000..187391f6 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventModule.java @@ -0,0 +1,181 @@ +package mineplex.gemhunters.worldevent; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.bukkit.event.EventHandler; + +import mineplex.core.MiniPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.account.permissions.Permission; +import mineplex.core.account.permissions.PermissionGroup; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextTop; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.worldevent.blizzard.BlizzardWorldEvent; +import mineplex.gemhunters.worldevent.command.WorldEventCommand; +import mineplex.gemhunters.worldevent.giant.GiantWorldEvent; +import mineplex.gemhunters.worldevent.gwenmart.GwenMartWorldEvent; +import mineplex.gemhunters.worldevent.ufo.UFOWorldEvent; +import mineplex.gemhunters.worldevent.wither.WitherWorldEvent; + +@ReflectivelyCreateMiniPlugin +public class WorldEventModule extends MiniPlugin +{ + public enum Perm implements Permission + { + WORLD_EVENT_COMMAND, + START_WORLD_EVENT_COMMAND, + STOP_WORLD_EVENT_COMMAND, + } + + private static final long EVENT_TIMER = TimeUnit.MINUTES.toMillis(30); + private static final long EVENT_COOLDOWN_TIMER = TimeUnit.MINUTES.toMillis(40); + private static final long COMPLETE_TIMER = TimeUnit.SECONDS.toMillis(30); + + private final List _events; + + private WorldEventModule() + { + super("World Event"); + + _events = Arrays.asList( + new GiantWorldEvent(), + new BlizzardWorldEvent(), + //new NetherPortalWorldEvent(), + new WitherWorldEvent(), + new GwenMartWorldEvent(), + new UFOWorldEvent() + ); + + generatePermissions(); + } + + private void generatePermissions() + { + PermissionGroup.ADMIN.setPermission(Perm.WORLD_EVENT_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.START_WORLD_EVENT_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.STOP_WORLD_EVENT_COMMAND, true, true); + } + + @Override + public void addCommands() + { + addCommand(new WorldEventCommand(this)); + } + + public void startEvent(WorldEventType eventType) + { + WorldEvent event = getEvent(eventType); + + event.setEventState(WorldEventState.WARMUP); + } + + public void startRandomEvent() + { + WorldEventType[] eventTypes = WorldEventType.values(); + Set possibleWorldEvents = new HashSet<>(); + + for (WorldEventType eventType : eventTypes) + { + if (UtilTime.elapsed(eventType.getLast(), EVENT_COOLDOWN_TIMER) || eventType.getPriority() == WorldEventPriority.TRIGGERED) + { + continue; + } + + possibleWorldEvents.add(eventType); + } + + if (possibleWorldEvents.isEmpty()) + { + return; + } + + startEvent(UtilAlg.Random(possibleWorldEvents)); + } + + @EventHandler + public void checkNextEvent(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + Iterator iterator = _events.iterator(); + + while (iterator.hasNext()) + { + WorldEvent worldEvent = iterator.next(); + + if (worldEvent.getEventState() == WorldEventState.COMPLETE && UtilTime.elapsed(worldEvent.getCompleteTime(), COMPLETE_TIMER)) + { + worldEvent.setEventState(null); + } + else if (worldEvent.getEventState() == WorldEventState.LIVE && worldEvent.checkToEnd()) + { + worldEvent.setEventState(WorldEventState.COMPLETE); + } + } + } + + @EventHandler + public void displayStatus(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC || !isEventActive()) + { + return; + } + + WorldEvent worldEvent = getActiveEvents().get(0); + + UtilTextTop.displayProgress(C.cRed + worldEvent.getEventType().getName() + C.cYellow + " -> " + C.cRed + worldEvent.getEventState().getName(), worldEvent.getProgress(), UtilServer.getPlayers()); + } + + public WorldEvent getEvent(WorldEventType eventType) + { + for (WorldEvent event : _events) + { + if (event.getEventType() == eventType) + { + return event; + } + } + + return null; + } + + public boolean isEventActive() + { + return !getActiveEvents().isEmpty(); + } + + public List getActiveEvents() + { + List events = new ArrayList<>(); + + for (WorldEvent event : _events) + { + if (event.isInProgress()) + { + events.add(event); + } + } + + return events; + } + + public long getEventTimer() + { + return EVENT_TIMER; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventPriority.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventPriority.java new file mode 100644 index 00000000..8aba307b --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventPriority.java @@ -0,0 +1,8 @@ +package mineplex.gemhunters.worldevent; + +public enum WorldEventPriority +{ + + GLOBAL, TRIGGERED + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventState.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventState.java new file mode 100644 index 00000000..e7babc0c --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventState.java @@ -0,0 +1,15 @@ +package mineplex.gemhunters.worldevent; + +public enum WorldEventState +{ + + WARMUP, + LIVE, + COMPLETE; + + public String getName() + { + return name().charAt(0) + name().toLowerCase().substring(1); + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventType.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventType.java new file mode 100644 index 00000000..32dbd527 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/WorldEventType.java @@ -0,0 +1,40 @@ +package mineplex.gemhunters.worldevent; + +public enum WorldEventType +{ + + GIANT("Zombie Awakening", WorldEventPriority.TRIGGERED), + BLZZARD("Hurricane", WorldEventPriority.GLOBAL), + NETHER("Dark Portal", WorldEventPriority.TRIGGERED), + WITHER("Wither Temple", WorldEventPriority.TRIGGERED), + GWEN_MART("Gwen-Mart Mega Sale", WorldEventPriority.GLOBAL), + UFO("UFO", WorldEventPriority.GLOBAL), + + ; + + private String _name; + private WorldEventPriority _priority; + private long _last; + + WorldEventType(String name, WorldEventPriority priority) + { + _name = name; + _priority = priority; + _last = 0; + } + + public String getName() + { + return _name; + } + + public WorldEventPriority getPriority() + { + return _priority; + } + + public long getLast() + { + return _last; + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/blizzard/BlizzardWorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/blizzard/BlizzardWorldEvent.java new file mode 100644 index 00000000..031abd34 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/blizzard/BlizzardWorldEvent.java @@ -0,0 +1,188 @@ +package mineplex.gemhunters.worldevent.blizzard; + +import java.util.concurrent.TimeUnit; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.weather.WeatherChangeEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.Managers; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.playerstatus.PlayerStatus; +import mineplex.gemhunters.playerstatus.PlayerStatusModule; +import mineplex.gemhunters.playerstatus.PlayerStatusType; +import mineplex.gemhunters.safezone.SafezoneModule; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventState; +import mineplex.gemhunters.worldevent.WorldEventType; + +public class BlizzardWorldEvent extends WorldEvent +{ + + private static final double START_CHANCE = 0.01; + private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(10); + private static final long GRACE_TIME = TimeUnit.SECONDS.toMillis(60); + private static final int DAMAGE = 2; + private static final String TIP = "EQUIP LEATHER ARMOUR OR GET NEAR A FIRE"; + + private final SafezoneModule _safezone; + private final PlayerStatusModule _playerStatus; + + private boolean _colour; + + public BlizzardWorldEvent() + { + super(WorldEventType.BLZZARD); + + _safezone = Managers.get(SafezoneModule.class); + _playerStatus = Managers.get(PlayerStatusModule.class); + } + + @EventHandler + public void trigger(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOWEST) + { + return; + } + + if (Math.random() < START_CHANCE) + { + setEventState(WorldEventState.LIVE); + } + } + + @EventHandler + public void weatherChange(WeatherChangeEvent event) + { + if (event.toWeatherState() && isEnabled()) + { + event.setCancelled(false); + } + } + + @EventHandler + public void damage(UpdateEvent event) + { + if (!isInProgress()) + { + return; + } + + if (!UtilTime.elapsed(_start, GRACE_TIME)) + { + if (event.getType() == UpdateType.SEC) + { + _colour = !_colour; + UtilTextBottom.display((_colour ? C.cRedB : C.cWhiteB) + "STORM COMING IN " + UtilTime.MakeStr(_start + GRACE_TIME - System.currentTimeMillis()) + " " + TIP, UtilServer.getPlayers()); + } + } + else if (isWarmup()) + { + setEventState(WorldEventState.LIVE); + + World world = _worldData.World; + + world.setStorm(true); + world.setThundering(true); + } + else if (event.getType() == UpdateType.SEC_05 && isLive()) + { + for (Player player : Bukkit.getOnlinePlayers()) + { + if (shouldDamage(player)) + { + _playerStatus.setStatus(player, PlayerStatusType.COLD); + _damage.NewDamageEvent(player, null, null, DamageCause.CUSTOM, DAMAGE, false, true, true, "Hurricane", "Frostbite"); + } + else + { + _playerStatus.setStatus(player, PlayerStatusType.WARM); + } + } + } + } + + private boolean shouldDamage(Player player) + { + String safezone = _safezone.getSafezone(player.getLocation()); + + if (safezone != null && safezone.contains(SafezoneModule.SAFEZONE_DATA_IGNORE)) + { + return false; + } + + for (Block block : UtilBlock.getInBoundingBox(player.getLocation().add(4, 2, 4), player.getLocation().subtract(4, 0, 4))) + { + if (block.getType() == Material.FIRE) + { + return false; + } + } + + for (ItemStack itemStack : player.getInventory().getArmorContents()) + { + if (!UtilItem.isLeatherProduct(itemStack)) + { + UtilTextBottom.display(C.cRedB + TIP, player); + player.sendMessage(F.main(_worldEvent.getName(), "Equip leather armor or get near a fire to stop taking damage!")); + return true; + } + } + + return false; + } + + @Override + public void onStart() + { + } + + @Override + public boolean checkToEnd() + { + return UtilTime.elapsed(_start, MAX_TIME); + } + + @Override + public void onEnd() + { + World world = _worldData.World; + + world.setStorm(false); + world.setThundering(false); + + for (Player player : Bukkit.getOnlinePlayers()) + { + _playerStatus.setStatus(player, PlayerStatusType.DANGER, true); + } + } + + @Override + public Location[] getEventLocations() + { + return null; + } + + @Override + public double getProgress() + { + return (double) (_start + MAX_TIME - System.currentTimeMillis()) / (double) MAX_TIME; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/StartCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/StartCommand.java new file mode 100644 index 00000000..83ce7b60 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/StartCommand.java @@ -0,0 +1,55 @@ +package mineplex.gemhunters.worldevent.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.gemhunters.worldevent.WorldEventModule; +import mineplex.gemhunters.worldevent.WorldEventType; + +public class StartCommand extends CommandBase +{ + public StartCommand(WorldEventModule plugin) + { + super(plugin, WorldEventModule.Perm.START_WORLD_EVENT_COMMAND, "start"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0) + { + caller.sendMessage(F.main(Plugin.getName(), "Starting a random world event.")); + Plugin.startRandomEvent(); + return; + } + + StringBuilder nameBuilder = new StringBuilder(); + + for (int i = 0; i < args.length; i++) + { + nameBuilder.append(args[i]); + nameBuilder.append(" "); + } + + String name = nameBuilder.toString().trim(); + + for (WorldEventType eventType : WorldEventType.values()) + { + if (name.equalsIgnoreCase(eventType.getName())) + { + caller.sendMessage(F.main(Plugin.getName(), "Starting the " + F.elem(eventType.getName()) + " world event.")); + Plugin.startEvent(eventType); + return; + } + } + + caller.sendMessage(F.main(Plugin.getName(), "I wasn\'t able to find a world event by the name " + F.elem(args[0]) + ". Possible values:")); + + for (WorldEventType eventType : WorldEventType.values()) + { + caller.sendMessage(C.cGray + "- " + F.elem(eventType.getName())); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/StopCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/StopCommand.java new file mode 100644 index 00000000..e095da6d --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/StopCommand.java @@ -0,0 +1,50 @@ +package mineplex.gemhunters.worldevent.command; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventModule; +import mineplex.gemhunters.worldevent.WorldEventState; + +public class StopCommand extends CommandBase +{ + public StopCommand(WorldEventModule plugin) + { + super(plugin, WorldEventModule.Perm.STOP_WORLD_EVENT_COMMAND, "stop"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0) + { + caller.sendMessage(F.main(Plugin.getName(), "Stopping all world events.")); + + for (WorldEvent event : Plugin.getActiveEvents()) + { + event.setEventState(WorldEventState.COMPLETE); + } + return; + } + + for (WorldEvent event : Plugin.getActiveEvents()) + { + if (args[0].equalsIgnoreCase(event.getEventType().name()) && event.getEventState() != WorldEventState.COMPLETE) + { + caller.sendMessage(F.main(Plugin.getName(), "Stopping " + F.elem(event.getEventType().name()) + ".")); + event.setEventState(WorldEventState.COMPLETE); + return; + } + } + + caller.sendMessage(F.main(Plugin.getName(), "I wasn\'t able to find an active world event by the name " + F.elem(args[0]) + ". Possible values:")); + + for (WorldEvent event : Plugin.getActiveEvents()) + { + caller.sendMessage(C.cGray + "- " + F.elem(event.getEventType().name())); + } + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/WorldEventCommand.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/WorldEventCommand.java new file mode 100644 index 00000000..568656f7 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/command/WorldEventCommand.java @@ -0,0 +1,27 @@ +package mineplex.gemhunters.worldevent.command; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import mineplex.core.command.MultiCommandBase; +import mineplex.core.common.util.F; +import mineplex.gemhunters.worldevent.WorldEventModule; + +public class WorldEventCommand extends MultiCommandBase +{ + public WorldEventCommand(WorldEventModule plugin) + { + super(plugin, WorldEventModule.Perm.WORLD_EVENT_COMMAND, "worldevent", "we"); + + AddCommand(new StartCommand(plugin)); + AddCommand(new StopCommand(plugin)); + } + + @Override + protected void Help(Player caller, String[] args) + { + caller.sendMessage(F.main(Plugin.getName(), "Command List:")); + caller.sendMessage(F.help("/" + _aliasUsed + " start [name]", "Starts a world event. Leaving [name] blank picks a random one.", ChatColor.DARK_RED)); + caller.sendMessage(F.help("/" + _aliasUsed + " stop [name]", "Stops a world event. Leaving [name] blank stops all events.", ChatColor.DARK_RED)); + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/giant/CustomGiant.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/giant/CustomGiant.java new file mode 100644 index 00000000..283c10c2 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/giant/CustomGiant.java @@ -0,0 +1,194 @@ +package mineplex.gemhunters.worldevent.giant; + +import java.util.ArrayList; +import java.util.Collection; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Giant; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.util.Vector; + +import mineplex.core.Managers; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.safezone.SafezoneModule; +import mineplex.gemhunters.spawn.SpawnModule; +import mineplex.minecraft.game.core.damage.DamageManager; + +public class CustomGiant implements Listener +{ + + private static final int GIANT_HEALTH = 500; + private static final int GIANT_WIDTH = 5; + private static final int GIANT_HEIGHT = 13; + private static final float DESTORY_FALLING_BLOCK_CHANCE = 0.04F; + private static final float MOVE_FACTOR = 0.3F; + private static final int MAX_SEARCH_DISTANCE_SQUARED = 2500; + private static final int TOO_CLOSE_DISTANCE_SQUARED = 625; + private static final int DAMAGE_RADIUS = 4; + private static final int DAMAGE = 4; + + private final DamageManager _damage; + private final SafezoneModule _safezone; + + private final Monster _giant; + + private final Location _fallback; + private Location _target; + + public CustomGiant(Location spawn) + { + _damage = Managers.require(DamageManager.class); + _safezone = Managers.require(SafezoneModule.class); + + spawn.getChunk().load(); + _giant = spawn.getWorld().spawn(spawn, Giant.class); + + _giant.setMaxHealth(GIANT_HEALTH); + _giant.setHealth(_giant.getMaxHealth()); + _giant.setRemoveWhenFarAway(false); + + UtilEnt.vegetate(_giant); + UtilEnt.ghost(_giant, true, false); + UtilEnt.setFakeHead(_giant, true); + + _fallback = Managers.get(SpawnModule.class).getCenter(); + } + + @EventHandler + public void updateMovement(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTEST || Bukkit.getOnlinePlayers().isEmpty()) + { + if (event.getType() == UpdateType.SEC) + { + _target = acquireTarget(); + } + + return; + } + + if (_target == null) + { + return; + } + + if (_target.equals(_fallback) && UtilMath.offsetSquared(_giant.getLocation(), _fallback) < TOO_CLOSE_DISTANCE_SQUARED) + { + return; + } + + if (_safezone.isInSafeZone(_giant.getLocation())) + { + _target = _fallback; + } + + Vector direction = UtilAlg.getTrajectory2d(_giant.getLocation(), _target).multiply(MOVE_FACTOR); + Location toTeleport = _giant.getLocation().add(direction); + Location heightCheck = _giant.getLocation().add(direction.clone().multiply(2)); + + if (Math.abs(UtilBlock.getHighest(_giant.getWorld(), heightCheck).getLocation().getY() - _giant.getLocation().getY()) <= 1) + { + toTeleport.add(0, 1, 0); + } + + toTeleport.setYaw(UtilAlg.GetYaw(direction)); + toTeleport.setPitch(UtilAlg.GetPitch(direction)); + + _giant.teleport(toTeleport); + } + + @EventHandler + public void updateBlockDestroy(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + for (Block block : UtilBlock.getInBoundingBox(_giant.getLocation().add(-GIANT_WIDTH, 1, -GIANT_WIDTH), _giant.getLocation().add(GIANT_WIDTH, GIANT_HEIGHT, GIANT_WIDTH))) + { + if (_safezone.isInSafeZone(block.getLocation())) + { + continue; + } + + if (Math.random() < DESTORY_FALLING_BLOCK_CHANCE) + { + FallingBlock fallingBlock = block.getWorld().spawnFallingBlock(block.getLocation(), block.getType(), block.getData()); + + fallingBlock.setDropItem(false); + fallingBlock.setHurtEntities(false); + fallingBlock.setVelocity(new Vector(UtilMath.random(-1, 1), UtilMath.random(0.5, 1), UtilMath.random(-1, 1))); + } + + block.setType(Material.AIR); + } + } + + @EventHandler + public void updateDamage(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + { + return; + } + + for (Player player : UtilPlayer.getInRadius(_giant.getLocation(), DAMAGE_RADIUS).keySet()) + { + _damage.NewDamageEvent(player, _giant, null, DamageCause.ENTITY_ATTACK, DAMAGE, true, true, false, UtilEnt.getName(_giant), "Zombie Awakening"); + } + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + if (event.getPlayer().equals(_target)) + { + _target = acquireTarget(); + } + } + + public Location acquireTarget() + { + Collection ignore = new ArrayList<>(); + + for (Player player : UtilServer.getPlayers()) + { + if (UtilPlayer.isSpectator(player) || _safezone.isInSafeZone(player.getLocation())) + { + ignore.add(player); + } + } + + Player player = UtilPlayer.getClosest(_giant.getLocation(), ignore); + + if (player == null) + { + return _fallback; + } + + return UtilMath.offsetSquared(_giant, player) > MAX_SEARCH_DISTANCE_SQUARED ? _fallback : player.getLocation(); + } + + public Monster getGiant() + { + return _giant; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/giant/GiantWorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/giant/GiantWorldEvent.java new file mode 100644 index 00000000..213b9a1a --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/giant/GiantWorldEvent.java @@ -0,0 +1,138 @@ +package mineplex.gemhunters.worldevent.giant; + +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.loot.rewards.LootChestReward; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventState; +import mineplex.gemhunters.worldevent.WorldEventType; + +public class GiantWorldEvent extends WorldEvent +{ + + private static final double START_CHANCE = 0.01; + private static final int MINI_ZOMBIES = 10; + private static final int MINI_ZOMBIES_MAX_DISTANCE_SQUARED = 2500; + private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(5); + private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(10); + + private CustomGiant _giant; + + public GiantWorldEvent() + { + super(WorldEventType.GIANT); + } + + @EventHandler + public void trigger(PlayerDeathEvent event) + { + if (Math.random() < START_CHANCE) + { + setEventState(WorldEventState.WARMUP); + } + } + + @Override + public void onStart() + { + _giant = new CustomGiant(_worldData.getCustomLocation("GIANT_SPAWN").get(0)); + addEntity(_giant.getGiant()); + + _worldEvent.registerEvents(_giant); + + setEventState(WorldEventState.LIVE); + } + + @Override + public boolean checkToEnd() + { + return UtilTime.elapsed(_start, MAX_TIME) || _giant.getGiant().isDead() || !_giant.getGiant().isValid(); + } + + @Override + public void onEnd() + { + ItemStack itemStack = SkinData.OMEGA_CHEST.getSkull(C.cAqua + "Omega Chest", new ArrayList<>()); + LootChestReward reward = new LootChestReward(CASH_OUT_DELAY, itemStack, "Omega", 1); + + _worldData.World.dropItemNaturally(getEventLocations()[0], itemStack); + + _loot.addItemReward(reward); + UtilServer.broadcast(F.main(_worldEvent.getName(), "The Giant has been killed! And has dropped loot!")); + + UtilServer.Unregister(_giant); + _giant = null; + } + + @Override + public Location[] getEventLocations() + { + return new Location[] { _giant.getGiant().getLocation() }; + } + + @Override + public double getProgress() + { + LivingEntity giant = _giant.getGiant(); + + return giant.getHealth() / giant.getMaxHealth(); + } + + @EventHandler + public void zombieCombust(EntityCombustEvent event) + { + if (_entities.contains(event.getEntity())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC || _giant == null) + { + return; + } + + for (Entity entity : _entities) + { + if (UtilMath.offsetSquared(entity, _giant.getGiant()) > MINI_ZOMBIES_MAX_DISTANCE_SQUARED) + { + entity.teleport(_giant.getGiant()); + } + } + + // -1 for the giant + if (_entities.size() - 1 < MINI_ZOMBIES) + { + Zombie zombie = _worldData.World.spawn(_giant.getGiant().getLocation(), Zombie.class); + + zombie.setRemoveWhenFarAway(false); + zombie.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 1)); + + addEntity(zombie); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/gwenmart/GwenMartWorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/gwenmart/GwenMartWorldEvent.java new file mode 100644 index 00000000..a827912c --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/gwenmart/GwenMartWorldEvent.java @@ -0,0 +1,172 @@ +package mineplex.gemhunters.worldevent.gwenmart; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.Managers; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventState; +import mineplex.gemhunters.worldevent.WorldEventType; + +public class GwenMartWorldEvent extends WorldEvent +{ + + private static final double START_CHANCE = 0.01; + private static final long WARMUP_TIME = TimeUnit.MINUTES.toMillis(3); + private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(8); + + private final BlockRestore _restore; + + private final Location _average; + private List _door; + private boolean _colour; + + public GwenMartWorldEvent() + { + super(WorldEventType.GWEN_MART); + + _restore = Managers.require(BlockRestore.class); + _average = UtilAlg.getAverageLocation(_worldData.getCustomLocation("GWEN_MART")); + _door = _worldData.getCustomLocation(String.valueOf(Material.EMERALD_BLOCK.getId())); + + _worldEvent.runSyncLater(() -> { + + for (Location location : _door) + { + location.getBlock().setType(Material.WOOD); + } + + }, 20); + } + + @EventHandler + public void trigger(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOWEST) + { + return; + } + + if (Math.random() < START_CHANCE) + { + setEventState(WorldEventState.LIVE); + } + } + + @EventHandler + public void updateOpening(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + _colour = !_colour; + + if (UtilTime.elapsed(_start, WARMUP_TIME) && isWarmup()) + { + for (Location location : _door) + { + _restore.add(location.getBlock(), 0, (byte) 0, Long.MAX_VALUE); + } + + for (Location location : _worldData.getCustomLocation("GWEN_MART_CHEST")) + { + location.getBlock().setType(Material.CHEST); + _loot.addSpawnedChest(location, getRandomChestKey()); + } + + setEventState(WorldEventState.LIVE); + } + else if (isLive()) + { + UtilTextBottom.display((_colour ? C.cDAquaB : C.cWhiteB) + "GWEN MART IS CLOSING IN " + UtilTime.MakeStr(_start + MAX_TIME - System.currentTimeMillis()), UtilServer.getPlayers()); + } + else if (isWarmup()) + { + UtilTextBottom.display((_colour ? C.cDAquaB : C.cWhiteB) + "GWEN MART IS OPENING IN " + UtilTime.MakeStr(_start + WARMUP_TIME - System.currentTimeMillis()), UtilServer.getPlayers()); + } + } + + @Override + public void onStart() + { + } + + @Override + public boolean checkToEnd() + { + return UtilTime.elapsed(_start, MAX_TIME); + } + + @Override + public void onEnd() + { + Location teleportTo = _worldData.getCustomLocation("GWEN_MART_TP").get(0); + + for (Player player : Bukkit.getOnlinePlayers()) + { + if (isInGwenMart(player.getLocation())) + { + player.leaveVehicle(); + player.teleport(teleportTo); + } + } + + for (Location location : _door) + { + _restore.restore(location.getBlock()); + } + } + + @Override + public Location[] getEventLocations() + { + return new Location[] { _average }; + } + + @Override + public double getProgress() + { + return (double) (_start + MAX_TIME - System.currentTimeMillis()) / (double) MAX_TIME; + } + + private boolean isInGwenMart(Location location) + { + List locations = _worldData.getCustomLocation("GWEN_MART"); + + return UtilAlg.inBoundingBox(location, locations.get(0), locations.get(1)); + } + + private String getRandomChestKey() + { + double random = Math.random(); + + if (random > 0.6) + { + return "ORANGE"; + } + else if (random > 0.1) + { + return "PINK"; + } + + return "GREEN"; + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/nether/NetherPortalWorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/nether/NetherPortalWorldEvent.java new file mode 100644 index 00000000..1d753026 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/nether/NetherPortalWorldEvent.java @@ -0,0 +1,215 @@ +package mineplex.gemhunters.worldevent.nether; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.Managers; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.utils.UtilVariant; +import mineplex.gemhunters.loot.rewards.LootChestReward; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventState; +import mineplex.gemhunters.worldevent.WorldEventType; + +public class NetherPortalWorldEvent extends WorldEvent +{ + + private static final int PORTALS = 5; + private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(20); + private static final int SKELETONS_PER_PORTAL = 10; + private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(10); + + private final BlockRestore _restore; + + private Player _player; + private List _portalLocations; + private List _portalBlocks; + private long _portalLit; + + public NetherPortalWorldEvent() + { + super(WorldEventType.NETHER); + + _restore = Managers.require(BlockRestore.class); + _portalLocations = new ArrayList<>(); + _portalBlocks = new ArrayList<>(50); + _portalLit = 0; + } + + @EventHandler + public void lightPortal(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R_BLOCK)) + { + return; + } + + Player player = event.getPlayer(); + Block block = event.getClickedBlock(); + + if (player.getItemInHand() == null || player.getItemInHand().getType() != Material.FLINT_AND_STEEL) + { + return; + } + + if (!_portalBlocks.contains(block)) + { + return; + } + + if (_portalLit == 0) + { + _portalLit = System.currentTimeMillis(); + + for (Location location : _portalLocations) + { + lightPortal(location); + } + + _player = player; + UtilServer.broadcast(F.main(_worldEvent.getName(), F.name(player.getName()) + " has lit a nether portal and become the " + F.color("Pumpkin King", C.cGold) + "! They now have 5 Omega Chests!")); + ItemStack itemStack = new ItemBuilder(Material.ENDER_CHEST).setTitle(C.cAqua + "5 Omega Chests").build(); + LootChestReward reward = new LootChestReward(CASH_OUT_DELAY, itemStack, "Omega", 5); + + _loot.addItemReward(reward); + + if (UtilInv.hasSpace(player, 1)) + { + reward.collectItem(player); + player.getInventory().addItem(itemStack); + } + else + { + _worldData.World.dropItemNaturally(player.getLocation(), itemStack); + } + + for (Location location : _portalLocations) + { + for (int i = 0; i < SKELETONS_PER_PORTAL; i++) + { + Skeleton skeleton = UtilVariant.spawnWitherSkeleton(location); + + skeleton.setCustomName(C.cGold + "Pumpkin Minions"); + skeleton.setCustomNameVisible(true); + + addEntity(skeleton); + } + } + + setEventState(WorldEventState.LIVE); + } + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + if (_player != null && event.getPlayer().equals(_player)) + { + setEventState(WorldEventState.COMPLETE); + } + } + + @EventHandler + public void entityTarget(EntityTargetEvent event) + { + if (_player != null && _entities.contains(event) && _player.equals(event.getTarget())) + { + event.setCancelled(true); + } + } + + @Override + public void onStart() + { + List storedLocations = _worldData.getCustomLocation("NETHER_PORTAL"); + + for (int i = 0; i < PORTALS; i++) + { + Location location = UtilAlg.Random(storedLocations); + + if (_portalLocations.contains(location)) + { + continue; + } + + _portalLocations.add(location); + buildPortal(location); + } + + UtilServer.broadcast(F.main(_worldEvent.getName(), "Portals have spawned around the map!")); + } + + @Override + public boolean checkToEnd() + { + return UtilTime.elapsed(_start, MAX_TIME); + } + + @Override + public void onEnd() + { + _portalLocations.clear(); + + for (Block block : _portalBlocks) + { + _restore.restore(block); + } + + _portalLit = 0; + } + + @Override + public Location[] getEventLocations() + { + return _portalLocations.toArray(new Location[0]); + } + + @Override + public double getProgress() + { + return (double) (_start + MAX_TIME - System.currentTimeMillis()) / (double) MAX_TIME; + } + + private void buildPortal(Location location) + { + location.getBlock().setType(Material.SPONGE); + + for (Block block : UtilBlock.getInBoundingBox(location.clone().add(2, 4, 0), location.clone().add(-2, 0, 0), false, true, false, false)) + { + _restore.add(block, Material.OBSIDIAN.getId(), (byte) 0, Integer.MAX_VALUE); + _portalBlocks.add(block); + } + } + + private void lightPortal(Location location) + { + for (Block block : UtilBlock.getInBoundingBox(location.clone().add(1, 3, 0), location.clone().add(-1, 1, 0), false, true, false, false)) + { + _restore.add(block, Material.PORTAL.getId(), (byte) 0, Integer.MAX_VALUE); + _portalBlocks.add(block); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/ufo/UFOWorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/ufo/UFOWorldEvent.java new file mode 100644 index 00000000..871edf36 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/ufo/UFOWorldEvent.java @@ -0,0 +1,204 @@ +package mineplex.gemhunters.worldevent.ufo; + +import mineplex.core.Managers; +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.SchematicData; +import mineplex.core.common.block.schematic.UtilSchematic; +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilTime; +import mineplex.core.utils.UtilVariant; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.loot.LootModule; +import mineplex.gemhunters.loot.rewards.LootChestReward; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventState; +import mineplex.gemhunters.worldevent.WorldEventType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.BlockVector; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +public class UFOWorldEvent extends WorldEvent +{ + + private static final String SCHEMATIC_PATH = ".." + File.separator + ".." + File.separator + "update" + File.separator + "files" + File.separator + "UFO.schematic"; + private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(10); + private static final ItemStack HELMET = new ItemStack(Material.GLASS); + private static final ItemStack SWORD = new ItemStack(Material.STONE_SWORD); + private static final ItemStack SWORD_LEADER = new ItemStack(Material.IRON_SWORD); + private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(10); + + private final EconomyModule _economy; + private final LootModule _loot; + + private Skeleton _leader; + private Set _skeletons; + private Set _ufoBlocks; + + public UFOWorldEvent() + { + super(WorldEventType.UFO); + + _economy = Managers.require(EconomyModule.class); + _loot = Managers.require(LootModule.class); + + _skeletons = new HashSet<>(); + _ufoBlocks = new HashSet<>(); + } + + @Override + public void onStart() + { + Location location = UtilAlg.Random(_worldData.getCustomLocation("NETHER_PORTAL")).clone().subtract(5, -10, 5); + Schematic schematic; + + try + { + schematic = UtilSchematic.loadSchematic(new File(SCHEMATIC_PATH)); + } + catch (IOException e) + { + e.printStackTrace(); + return; + } + + SchematicData data = schematic.paste(location, false, false, false); + + for (BlockVector vector : data.getBlocks()) + { + Location block = location.add(vector); + + _ufoBlocks.add(block.getBlock()); + + location.subtract(vector); + } + + _leader = UtilVariant.spawnWitherSkeleton(location); + _leader.setMaxHealth(200); + _leader.setHealth(_leader.getMaxHealth()); + _leader.getEquipment().setItemInHand(SWORD_LEADER); + _leader.setCustomName(C.cDGreenB + "Alien Leader"); + prepareSkeleton(_leader); + + for (int i = 0; i < 10; i++) + { + Skeleton skeleton = _leader.getWorld().spawn(location, Skeleton.class); + skeleton.getEquipment().setItemInHand(SWORD); + skeleton.setCustomName(C.cGreenB + "Alien"); + prepareSkeleton(skeleton); + _skeletons.add(skeleton); + } + + setEventState(WorldEventState.LIVE); + } + + private void prepareSkeleton(Skeleton skeleton) + { + skeleton.getEquipment().setHelmet(HELMET); + skeleton.setRemoveWhenFarAway(false); + skeleton.setCustomNameVisible(true); + } + + @EventHandler + public void entityDeath(EntityDeathEvent event) + { + LivingEntity entity = event.getEntity(); + + if (_skeletons.remove(entity)) + { + event.getDrops().clear(); + event.setDroppedExp(0); + + Player killer = entity.getKiller(); + + if (killer != null) + { + _economy.addToStore(killer, "Killing an Alien", 10); + } + } + + if (_leader != null && _leader.equals(entity)) + { + Player killer = _leader.getKiller(); + + if (killer != null) + { + ItemStack itemStack = SkinData.OMEGA_CHEST.getSkull(C.cAqua + "Omega Chest", new ArrayList<>()); + LootChestReward reward = new LootChestReward(CASH_OUT_DELAY, itemStack, "Omega", 1); + _leader.getWorld().dropItemNaturally(_leader.getEyeLocation(), itemStack); + _loot.addItemReward(reward); + _economy.addToStore(killer, "Killing The Alien Leader", 1000); + } + } + } + + @EventHandler + public void entityDamage(EntityCombustEvent event) + { + Entity entity = event.getEntity(); + + if (entity.equals(_leader) || _skeletons.contains(entity)) + { + event.setCancelled(true); + } + } + + @Override + public boolean checkToEnd() + { + return _leader.isDead() || UtilTime.elapsed(_start, MAX_TIME); + } + + @Override + public void onEnd() + { + _leader.remove(); + + for (Skeleton skeleton : _skeletons) + { + skeleton.remove(); + } + + _skeletons.clear(); + + for (Block block : _ufoBlocks) + { + block.setType(Material.AIR); + } + + _ufoBlocks.clear(); + } + + @Override + public Location[] getEventLocations() + { + return new Location[]{_leader.getLocation()}; + } + + @Override + public double getProgress() + { + return _leader.getHealth() / _leader.getMaxHealth(); + } +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/wither/WitherWorldEvent.java b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/wither/WitherWorldEvent.java new file mode 100644 index 00000000..3e263c04 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/src/mineplex/gemhunters/worldevent/wither/WitherWorldEvent.java @@ -0,0 +1,159 @@ + +package mineplex.gemhunters.worldevent.wither; + +import java.util.concurrent.TimeUnit; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilTime; +import mineplex.core.utils.UtilVariant; +import mineplex.gemhunters.worldevent.WorldEvent; +import mineplex.gemhunters.worldevent.WorldEventState; +import mineplex.gemhunters.worldevent.WorldEventType; + +public class WitherWorldEvent extends WorldEvent +{ + + private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(5); + private static final int SKELETONS = 5; + private static final ItemStack IN_HAND = new ItemStack(Material.STONE_SWORD); + private static final int HEALTH = 40; + private static final int RADIUS = 5; + + private Location[] _skulls; + + public WitherWorldEvent() + { + super(WorldEventType.WITHER); + + _worldEvent.runSyncLater(() -> buildAlter(), 20); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void trigger(BlockPlaceEvent event) + { + if (_skulls == null) + { + return; + } + + Player player = event.getPlayer(); + Block block = event.getBlock(); + boolean start = true; + + // Check for allowed placement + for (Location location : _skulls) + { + if (block.getLocation().equals(location)) + { + event.setCancelled(false); + player.sendMessage(F.main(_worldEvent.getName(), "grrrrr....")); + break; + } + } + + // Check for all skulls + for (Location location : _skulls) + { + if (location.getBlock().getType() != Material.SKULL) + { + start = false; + } + } + + // Start Event + if (start) + { + setEventState(WorldEventState.WARMUP); + } + } + + @Override + public void onStart() + { + Location location = _worldData.getCustomLocation("WITHER_ALTER").get(0).clone().add(0, 1, 0); + + for (Location skull : _skulls) + { + skull.getBlock().setType(Material.AIR); + } + + Block chest = location.getBlock().getRelative(BlockFace.UP); + + chest.setType(Material.ENDER_CHEST); + _loot.addSpawnedChest(chest.getLocation(), "PURPLE"); + + for (int i = 0; i < SKELETONS; i++) + { + Skeleton skeleton = UtilVariant.spawnWitherSkeleton(UtilAlg.getRandomLocation(location, RADIUS, 0, RADIUS)); + + skeleton.getEquipment().setItemInHand(IN_HAND); + skeleton.setMaxHealth(HEALTH); + skeleton.setHealth(HEALTH); + + addEntity(skeleton); + } + + setEventState(WorldEventState.LIVE); + } + + @Override + public boolean checkToEnd() + { + return UtilTime.elapsed(_start, MAX_TIME) || _entities.isEmpty(); + } + + @Override + public void onEnd() + { + for (Location location : _skulls) + { + location.getBlock().setType(Material.AIR); + } + } + + @Override + public Location[] getEventLocations() + { + return new Location[] { _skulls[1] }; + } + + @Override + public double getProgress() + { + return (double) (_start + MAX_TIME - System.currentTimeMillis()) / (double) MAX_TIME; + } + + private void buildAlter() + { + Location point = _worldData.getCustomLocation("WITHER_ALTER").get(0).clone(); + + point.getBlock().setType(Material.SOUL_SAND); + point.add(0, 1, 0).getBlock().setType(Material.SOUL_SAND); + point.add(0, 0, -1).getBlock().setType(Material.SOUL_SAND); + point.add(0, 0, 2).getBlock().setType(Material.SOUL_SAND); + + _skulls = new Location[] { + point.add(0, 1, 0), + point.add(0, 0, -1), + point.add(0, 0, -1) + }; + + for (Location location : _skulls) + { + location.getBlock().setType(Material.SPONGE); + } + } + +} diff --git a/Plugins[Modified]/mineplex-game-gemhunters/target/classes/plugin.yml b/Plugins[Modified]/mineplex-game-gemhunters/target/classes/plugin.yml new file mode 100644 index 00000000..a5af44c6 --- /dev/null +++ b/Plugins[Modified]/mineplex-game-gemhunters/target/classes/plugin.yml @@ -0,0 +1,3 @@ +name: GemHunters +main: mineplex.gemhunters.GemHunters +version: 0.1 diff --git a/Plugins[Modified]/mineplex-google-sheets/pom.xml b/Plugins[Modified]/mineplex-google-sheets/pom.xml new file mode 100644 index 00000000..9a70533c --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/pom.xml @@ -0,0 +1,67 @@ + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + Google Sheets + mineplex-google-sheets + + + + com.googlecode.json-simple + json-simple + 1.1.1 + compile + + + org.json + json + 20160212 + compile + + + com.google.api-client + google-api-client + 1.22.0 + compile + + + com.google.oauth-client + google-oauth-client-jetty + 1.22.0 + compile + + + com.google.apis + google-api-services-sheets + v4-rev20-1.22.0 + compile + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + lib/ + mineplex.googlesheets.GoogleSheetController + + + + + + + + \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/GoogleSheetController.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/GoogleSheetController.java new file mode 100644 index 00000000..2d5e6bec --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/GoogleSheetController.java @@ -0,0 +1,29 @@ +package mineplex.googlesheets; + +import java.awt.*; + +import mineplex.googlesheets.sheetparser.SheetProviderImpl; +import mineplex.googlesheets.skinhelper.SkinHelperUI; + +public class GoogleSheetController +{ + + public static void main(String[] args) + { + String module = System.getProperty("module"); + + if (module == null || module.equalsIgnoreCase("sheetparser")) + { + new SheetProviderImpl(); + } + else if (module.equalsIgnoreCase("skinhelper")) + { + EventQueue.invokeLater(() -> + { + SkinHelperUI frame = new SkinHelperUI(); + frame.setVisible(true); + }); + } + } + +} diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/SpreadsheetType.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/SpreadsheetType.java new file mode 100644 index 00000000..0f011dfa --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/SpreadsheetType.java @@ -0,0 +1,27 @@ +package mineplex.googlesheets; + +/** + * An enum containing all the google spreadsheet links relating to Mineplex.
+ */ +public enum SpreadsheetType +{ + + GEM_HUNTERS_CHESTS("11Noztgbpu_gUKkc5F4evKKfyxS-Jv1coE0IrBToX_gg"), + GEM_HUNTERS_SHOP("1OcYktxVZaW6Fm29Zh6w4Lb-UVyuN8r1x-TFb_3USYYI"), + MOBA_SKINS("1bgTz46jdnaywOXlmkWKZ5LNWfTDFGTzrTI7QrVEtkDA"), + QUESTS_SHEET("1Gy1a7GCVopmOLwYE3Sk1DNVCAIwT8ReaLu4wRe0sfDE"), + SMASH_KITS("1Z_SLBzjiIVqu25PMGw9TwNKR3wd9Y9sX7rSDBl_rpxk"), + ; + + private String _id; + + SpreadsheetType(String id) + { + _id = id; + } + + public String getId() + { + return _id; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/sheetparser/SheetProvider.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/sheetparser/SheetProvider.java new file mode 100644 index 00000000..bc2e3a81 --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/sheetparser/SheetProvider.java @@ -0,0 +1,177 @@ +package mineplex.googlesheets.sheetparser; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.JSONArray; +import org.json.JSONObject; + +import com.google.api.client.auth.oauth2.Credential; +import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; +import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; +import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; +import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.client.util.store.FileDataStoreFactory; +import com.google.api.services.sheets.v4.Sheets; +import com.google.api.services.sheets.v4.SheetsScopes; +import com.google.api.services.sheets.v4.model.Sheet; +import com.google.api.services.sheets.v4.model.Spreadsheet; + +import mineplex.googlesheets.SpreadsheetType; + +/** + * A provider class designed with the functionality to get data from a Google Spreadsheet.
+ * Then proceed to return this data within the context of a {@link JSONObject}. + */ +public class SheetProvider +{ + + /** Service name. */ + private static final String APPLICATION_NAME = "Mineplex Google Sheets"; + + /** Directory to store user credentials for the service. */ + private static final File DATA_STORE_DIR = new File(".." + File.separatorChar + ".." + File.separatorChar + "update" + File.separatorChar + "files"); + + /** Global instance of the {@link FileDataStoreFactory}. */ + private static FileDataStoreFactory DATA_STORE_FACTORY; + + /** Global instance of the JSON factory. */ + private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); + + /** Global instance of the HTTP transport. */ + private static HttpTransport HTTP_TRANSPORT; + + /** List of all permissions that the service requires */ + private static final List SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS); + + private Sheets _service; + private Credential _credential; + + static + { + try + { + HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); + DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + public SheetProvider() + { + try + { + _credential = authorize(); + _service = getSheetsService(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * Creates an authorized Credential object. + * + * @return an authorized Credential object. + * @throws IOException If the Credential fails to authorise. + */ + private Credential authorize() throws IOException + { + // Load client secrets. + InputStream in = new FileInputStream(DATA_STORE_DIR + File.separator + "client_secret.json"); + GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in)); + + // Build flow and trigger user authorization request. + GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build(); + return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user"); + } + + /** + * Build and return an authorized Sheets API client service. + * + * @return an authorized Sheets API client service + */ + private Sheets getSheetsService() + { + return new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, _credential).setApplicationName(APPLICATION_NAME).build(); + } + + /** + * Returns the data comprised inside a Google Spreadsheet in the context of a {@link JSONObject}. + * + * @param spreadsheet The {@link SpreadsheetType} that you need to get the data from. + * @return A {@link JSONObject} containing all the data about a spreadsheet mapped by sheet -> rows -> columns. + */ + public JSONObject asJSONObject(SpreadsheetType spreadsheet) + { + JSONObject parent = new JSONObject(); + JSONArray array = new JSONArray(); + Map>> valuesMap = get(spreadsheet); + + if (valuesMap == null) + { + return null; + } + + valuesMap.forEach((sheetName, lists) -> + { + List> values = valuesMap.get(sheetName); + + JSONObject object = new JSONObject(); + + object.put("name", sheetName); + object.put("values", values); + + array.put(object); + }); + + parent.put("data", array); + return parent; + } + + private Map>> get(SpreadsheetType spreadsheet) + { + try + { + Spreadsheet googleSpreadsheet = _service.spreadsheets().get(spreadsheet.getId()).execute(); + List sheets = googleSpreadsheet.getSheets(); + Map>> valuesMap = new HashMap<>(sheets.size()); + + for (Sheet sheet : sheets) + { + String name = sheet.getProperties().getTitle(); + + valuesMap.put(name, get(spreadsheet, name)); + } + + return valuesMap; + } + catch (IOException e) + { + e.printStackTrace(); + } + + return null; + } + + private List> get(SpreadsheetType spreadsheet, String sheetName) throws IOException + { + return _service.spreadsheets().values().get(spreadsheet.getId(), sheetName).execute().getValues(); + } + +} diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/sheetparser/SheetProviderImpl.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/sheetparser/SheetProviderImpl.java new file mode 100644 index 00000000..36618657 --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/sheetparser/SheetProviderImpl.java @@ -0,0 +1,82 @@ +package mineplex.googlesheets.sheetparser; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import org.json.JSONObject; + +import mineplex.googlesheets.SpreadsheetType; + +public class SheetProviderImpl +{ + + private static final int SLEEP_TIME = 1000; + private static final String DATA_STORE_DIR = ".." + File.separatorChar + ".." + File.separatorChar + "update" + File.separatorChar + "files"; + + public SheetProviderImpl() + { + String sheetToRead = System.getProperty("sheet"); + SpreadsheetType[] types; + + if (sheetToRead == null) + { + types = SpreadsheetType.values(); + } + else + { + types = new SpreadsheetType[]{SpreadsheetType.valueOf(sheetToRead)}; + } + + System.out.println("Loading Sheet Provider"); + SheetProvider provider = new SheetProvider(); + System.out.println("Loaded Sheet Provider"); + + for (SpreadsheetType type : types) + { + System.out.println("Sleeping..."); + try + { + Thread.sleep(SLEEP_TIME); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + System.out.println("Getting data for " + type.name() + " (" + type.getId() + ")"); + + JSONObject object = provider.asJSONObject(type); + + System.out.println("Done"); + System.out.println("Saving to file..."); + + File dir = new File(DATA_STORE_DIR); + File file = new File(dir + File.separator + type.name() + ".json"); + + if (!dir.exists()) + { + dir.mkdirs(); + } + + try + { + System.out.println("Deleting"); + file.delete(); + System.out.println("Creating a new file"); + file.createNewFile(); + + FileWriter writer = new FileWriter(file); + + System.out.println("Writing"); + writer.write(object.toString()); + + System.out.println("Closing..."); + writer.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } +} diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/skinhelper/SkinHelperUI.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/skinhelper/SkinHelperUI.java new file mode 100644 index 00000000..01aeea6a --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/skinhelper/SkinHelperUI.java @@ -0,0 +1,128 @@ +package mineplex.googlesheets.skinhelper; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import mineplex.googlesheets.util.SkinFetcher; +import mineplex.googlesheets.util.UUIDFetcher; + +public class SkinHelperUI extends JFrame +{ + + private static final Map UUID_CACHE = new HashMap<>(); + + private static final Font FONT = new Font("Verdana", Font.PLAIN, 12); + private static final long FETCH_WAIT_TIME = 30; + private static final long FETCH_WAIT_MILLISECONDS = TimeUnit.SECONDS.toMillis(FETCH_WAIT_TIME); + + private long _lastFetch; + + public SkinHelperUI() + { + setTitle("Skin Helper"); + setResizable(false); + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setBounds(100, 100, 150, 300); + JPanel contentPane = new JPanel(); + contentPane.setBackground(Color.DARK_GRAY); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + + JTextField txtMinecraftName = new JTextField(); + txtMinecraftName.setFont(FONT); + txtMinecraftName.setForeground(Color.WHITE); + txtMinecraftName.setBackground(Color.GRAY); + txtMinecraftName.setBounds(10, 55, 124, 20); + txtMinecraftName.setColumns(10); + contentPane.add(txtMinecraftName); + + JLabel lblMinecraftName = new JLabel("Minecraft Name"); + lblMinecraftName.setForeground(Color.WHITE); + lblMinecraftName.setFont(FONT); + lblMinecraftName.setBounds(10, 30, 100, 14); + contentPane.add(lblMinecraftName); + + JButton btnOk = new JButton("OK"); + btnOk.setForeground(Color.WHITE); + btnOk.setBackground(Color.DARK_GRAY); + btnOk.setBounds(10, 86, 124, 23); + contentPane.add(btnOk); + + JLabel lblSkinValue = new JLabel("Skin Value"); + lblSkinValue.setForeground(Color.WHITE); + lblSkinValue.setFont(FONT); + lblSkinValue.setBounds(10, 120, 100, 14); + contentPane.add(lblSkinValue); + + JTextField txtSkinValue = new JTextField(); + txtSkinValue.setEditable(false); + txtSkinValue.setForeground(Color.WHITE); + txtSkinValue.setBackground(Color.GRAY); + txtSkinValue.setFont(FONT); + txtSkinValue.setColumns(10); + txtSkinValue.setBounds(10, 145, 124, 20); + contentPane.add(txtSkinValue); + + JLabel lblSkinSignature = new JLabel("Skin Signature"); + lblSkinSignature.setForeground(Color.WHITE); + lblSkinSignature.setFont(FONT); + lblSkinSignature.setBounds(10, 176, 100, 14); + contentPane.add(lblSkinSignature); + + JTextField txtSkinSignature = new JTextField(); + txtSkinSignature.setEditable(false); + txtSkinSignature.setForeground(Color.WHITE); + txtSkinSignature.setBackground(Color.GRAY); + txtSkinSignature.setFont(FONT); + txtSkinSignature.setColumns(10); + txtSkinSignature.setBounds(10, 201, 124, 20); + contentPane.add(txtSkinSignature); + + btnOk.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent event) + { + if (System.currentTimeMillis() - _lastFetch < FETCH_WAIT_MILLISECONDS) + { + JOptionPane.showMessageDialog(SkinHelperUI.this, "You must wait a minimum of " + FETCH_WAIT_TIME + " seconds between each skin fetch to prevent you from being blocked from using the Mojang API."); + return; + } + + txtSkinValue.setText("Fetching..."); + txtSkinSignature.setText(txtSkinValue.getText()); + + try + { + String input = txtMinecraftName.getText(); + String uuid = UUID_CACHE.get(input); + + if (uuid == null) + { + uuid = UUIDFetcher.getPlayerUUIDNoDashes(input); + UUID_CACHE.put(input, uuid); + } + + String[] skinData = SkinFetcher.getSkinData(uuid); + + txtSkinValue.setText(skinData[0]); + txtSkinSignature.setText(skinData[1]); + + _lastFetch = System.currentTimeMillis(); + } + catch (Exception e) + { + e.printStackTrace(); + JOptionPane.showMessageDialog(SkinHelperUI.this, "Please check the Minecraft Name you have entered. If it is correct please wait a minute and try again."); + } + } + }); + } +} diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/SkinFetcher.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/SkinFetcher.java new file mode 100644 index 00000000..cbc9d02a --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/SkinFetcher.java @@ -0,0 +1,25 @@ +package mineplex.googlesheets.util; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +public class SkinFetcher +{ + + private static final String SKIN_URL = "https://sessionserver.mojang.com/session/minecraft/profile/UUID?unsigned=false"; + + public static String[] getSkinData(String uuid) throws Exception + { + String[] skinData = new String[2]; + JSONObject object = UtilJSON.getFromURL(SKIN_URL.replaceFirst("UUID", uuid)); + JSONArray properties = (JSONArray) object.get("properties"); + + JSONObject innerObject = (JSONObject) properties.get(0); + + skinData[1] = (String) innerObject.get("signature"); + skinData[0] = (String) innerObject.get("value"); + + return skinData; + } + +} diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/UUIDFetcher.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/UUIDFetcher.java new file mode 100644 index 00000000..92c50787 --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/UUIDFetcher.java @@ -0,0 +1,62 @@ +package mineplex.googlesheets.util; + +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Collections; +import java.util.List; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +/** + * A utility to fetch UUIDs based on a player's name. + * Adapted from UUIDFetcher inside Core.Common. + */ +public class UUIDFetcher +{ + + private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft"; + private static final JSONParser PARSER = new JSONParser(); + + public static String getPlayerUUIDNoDashes(String name) throws Exception + { + String uuid = null; + List nameList = Collections.singletonList(name); + + HttpURLConnection connection = createConnection(); + String body = JSONArray.toJSONString(nameList); + writeBody(connection, body); + JSONArray array = (JSONArray) PARSER.parse(new InputStreamReader(connection.getInputStream())); + + for (Object profile : array) + { + JSONObject jsonProfile = (JSONObject) profile; + uuid = (String) jsonProfile.get("id"); + } + + return uuid; + } + + private static void writeBody(HttpURLConnection connection, String body) throws Exception + { + OutputStream stream = connection.getOutputStream(); + stream.write(body.getBytes()); + stream.flush(); + stream.close(); + } + + private static HttpURLConnection createConnection() throws Exception + { + URL url = new URL(PROFILE_URL); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setUseCaches(false); + connection.setDoInput(true); + connection.setDoOutput(true); + return connection; + } +} \ No newline at end of file diff --git a/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/UtilJSON.java b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/UtilJSON.java new file mode 100644 index 00000000..5488d321 --- /dev/null +++ b/Plugins[Modified]/mineplex-google-sheets/src/mineplex/googlesheets/util/UtilJSON.java @@ -0,0 +1,41 @@ +package mineplex.googlesheets.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.nio.charset.Charset; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +public class UtilJSON +{ + + private static final JSONParser PARSER = new JSONParser(); + + private static String readAll(Reader rd) throws IOException + { + StringBuilder sb = new StringBuilder(); + int cp; + while ((cp = rd.read()) != -1) + { + sb.append((char) cp); + } + return sb.toString(); + } + + public static JSONObject getFromURL(String url) throws IOException, ParseException + { + try (InputStream is = new URL(url).openStream()) + { + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + String jsonText = readAll(rd); + return (JSONObject) PARSER.parse(jsonText); + } + } + +} diff --git a/Plugins[Modified]/out/Arcade.jar b/Plugins[Modified]/out/Arcade.jar deleted file mode 100644 index 99547839..00000000 Binary files a/Plugins[Modified]/out/Arcade.jar and /dev/null differ diff --git a/Plugins[Modified]/out/Hub.jar b/Plugins[Modified]/out/Hub.jar index bd659983..4336ac8f 100644 Binary files a/Plugins[Modified]/out/Hub.jar and b/Plugins[Modified]/out/Hub.jar differ diff --git a/Plugins[Modified]/out/MapParser.jar b/Plugins[Modified]/out/MapParser.jar deleted file mode 100644 index 4a2d59fa..00000000 Binary files a/Plugins[Modified]/out/MapParser.jar and /dev/null differ diff --git a/Plugins[Modified]/out/NanoGames.jar b/Plugins[Modified]/out/NanoGames.jar deleted file mode 100644 index 2773fcab..00000000 Binary files a/Plugins[Modified]/out/NanoGames.jar and /dev/null differ diff --git a/Plugins[Modified]/out/StaffServer.jar b/Plugins[Modified]/out/StaffServer.jar deleted file mode 100644 index 5d8c3e74..00000000 Binary files a/Plugins[Modified]/out/StaffServer.jar and /dev/null differ diff --git a/Plugins[Modified]/plugin.xml b/Plugins[Modified]/plugin.xml index e9a58a1b..b9b1d368 100644 --- a/Plugins[Modified]/plugin.xml +++ b/Plugins[Modified]/plugin.xml @@ -1,4 +1,3 @@ - 4.0.0 @@ -57,4 +56,4 @@ - + \ No newline at end of file diff --git a/Plugins[Modified]/pom.xml b/Plugins[Modified]/pom.xml index fb1747fc..24d50310 100644 --- a/Plugins[Modified]/pom.xml +++ b/Plugins[Modified]/pom.xml @@ -21,27 +21,67 @@ Mineplex.Core.Common Mineplex.Core.Common.Base Mineplex.Database + Mineplex.Hub + Mineplex.MapParser Mineplex.Minecraft.Game.ClassCombat Mineplex.Minecraft.Game.Core Mineplex.ServerData + Mineplex.ServerMonitor Mineplex.StaffServer - Mineplex.MapParser Mineplex.Game.Nano - Mineplex.Hub Nautilus.Game.Arcade - + Nautilus.Game.Arcade.UHC.WorldGen + mineplex-game-gemhunters + + - + + - com.labalityowo - spigot - file://D:\Stuff\Memeplex\Plugins\lib + spigotmc-public + https://hub.spigotmc.org/nexus/content/groups/public/ + + + com.mineplex + file://${project.basedir}/lib + + com.mineplex + spigot + 1.0 + compile + + + com.google.guava + guava + + + commons-io commons-io @@ -54,6 +94,12 @@ 1.6 compile + + com.google.code.gson + gson + 2.2.1 + compile + com.vexsoftware votifier @@ -84,6 +130,12 @@ 6.0.0 compile + + net.md-5 + bungeecord-proxy + 1.8-SNAPSHOT + provided + org.apache.commons commons-dbcp2 @@ -114,6 +166,12 @@ 3.5.2 compile + + org.spigotmc + spigot-api + 1.12-R0.1-SNAPSHOT + compile + redis.clients jedis @@ -132,18 +190,6 @@ 1.3 test - - com.labalityowo - spigot - 1.0 - provided - - - com.google.guava - guava - - - @@ -171,7 +217,6 @@ org.apache.maven.plugins maven-jar-plugin - 3.0.2 @@ -188,6 +233,39 @@ maven-jar-plugin 3.0.2 + + org.apache.maven.plugins + maven-shade-plugin + 2.4.2 + + false + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + net.md-5 + scriptus + [0.3.1,) + + describe + + + + + + + + + +