package mineplex.hub.server; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bukkit.ChatColor; 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.EventPriority; import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerPortalEvent; 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.CoreClientManager; import mineplex.core.common.Rank; import mineplex.core.common.util.C; import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.donation.DonationManager; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.logger.Logger; import mineplex.core.portal.Portal; import mineplex.core.recharge.Recharge; import mineplex.core.shop.ShopBase; import mineplex.core.status.ServerStatusData; import mineplex.core.status.ServerStatusManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.HubManager; import mineplex.hub.modules.StackerManager; import mineplex.hub.party.Party; import mineplex.hub.party.PartyManager; import mineplex.hub.queue.QueueManager; import mineplex.hub.queue.ui.QueueShop; import mineplex.hub.server.ui.LobbyShop; import mineplex.hub.server.ui.QuickShop; import mineplex.hub.server.ui.ServerNpcShop; public class ServerManager extends MiniPlugin { private static final Long FREE_PORTAL_TIMER = 20000L; private CoreClientManager _clientManager; private DonationManager _donationManager; private Portal _portal; private PartyManager _partyManager; private ServerStatusManager _statusManager; private HubManager _hubManager; private StackerManager _stackerManager; private QueueManager _queueManager; private NautHashMap> _serverKeyInfoMap = new NautHashMap>(); private NautHashMap _serverKeyTagMap = new NautHashMap(); private NautHashMap _serverNpcShopMap = new NautHashMap(); private NautHashMap _serverInfoMap = new NautHashMap(); private NautHashMap _serverUpdate = new NautHashMap(); private NautHashMap _serverPortalLocations = new NautHashMap(); // Join Time for Free Players Timer private NautHashMap _freeJoinTime = new NautHashMap(); private QueueShop _domShop; private QuickShop _quickShop; private LobbyShop _lobbyShop; private boolean _alternateUpdateFire = false; private boolean _retrieving = false; private long _lastRetrieve = 0; public ServerManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, Portal portal, PartyManager partyManager, ServerStatusManager statusManager, HubManager hubManager, StackerManager stackerManager, QueueManager queueManager) { super("Server Manager", plugin); _clientManager = clientManager; _donationManager = donationManager; _portal = portal; _partyManager = partyManager; _statusManager = statusManager; _hubManager = hubManager; _stackerManager = stackerManager; _queueManager = queueManager; plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, "BungeeCord"); LoadServers(); _quickShop = new QuickShop(this, clientManager, donationManager, "Quick Menu"); _lobbyShop = new LobbyShop(this, clientManager, donationManager, "Lobby Menu"); //_domShop = new new QueueShop(_queueManager, clientManager, donationManager, "Dominate"); } @EventHandler(priority = EventPriority.LOW) public void playerPortalEvent(PlayerPortalEvent event) { event.setCancelled(true); } @EventHandler(priority = EventPriority.LOW) public void entityPortalEvent(EntityPortalEvent event) { event.setCancelled(true); } @EventHandler(priority = EventPriority.LOW) public void playerCheckPortalEvent(EntityPortalEnterEvent event) { if (!(event.getEntity() instanceof Player)) { if (event.getEntity() instanceof LivingEntity) UtilAction.velocity(event.getEntity(), UtilAlg.getTrajectory(event.getEntity().getLocation(), _hubManager.GetSpawn()), 1, true, 0.8, 0, 1, true); return; } final Player player = (Player)event.getEntity(); if (!Recharge.Instance.use(player, "Portal Server", 1000, false, false)) return; long timeUntilPortal = getMillisecondsUntilPortal(player); if (!_hubManager.CanPortal(player) || timeUntilPortal > 0) { if (timeUntilPortal > 0) { player.playSound(player.getEyeLocation(), Sound.CHICKEN_EGG_POP, 2, 2); UtilPlayer.message(player, F.main("Server Portal", "You cannot join a server for " + C.cGreen + UtilTime.convertString(timeUntilPortal, 0, TimeUnit.SECONDS))); } UtilAction.velocity(player, UtilAlg.getTrajectory(player.getLocation(), _hubManager.GetSpawn()), 1.5, true, 0.8, 0, 1.0, true); // Need to set their velocity again a tick later // Setting Y-Velocity while in a portal doesn't seem to do anything... Science! _plugin.getServer().getScheduler().runTask(_plugin, new Runnable() { @Override public void run() { if (player != null && player.isOnline()) { UtilAction.velocity(player, UtilAlg.getTrajectory(player.getLocation(), _hubManager.GetSpawn()), 1, true, 0.5, 0, 1.0, true); } } }); return; } String serverName = _serverPortalLocations.get(player.getLocation().getBlock().getLocation().toVector()); if (serverName != null) { List serverList = new ArrayList(GetServerList(serverName)); int slots = 1; if (serverList.size() > 0) { slots = GetRequiredSlots(player, serverList.get(0).ServerType); } try { Collections.sort(serverList, new ServerSorter(slots)); boolean hasUltra = _clientManager.Get(player).GetRank().Has(Rank.ULTRA); for (ServerInfo serverInfo : serverList) { if ((serverInfo.MOTD.contains("Starting") || serverInfo.MOTD.contains("Recruiting") || serverInfo.MOTD.contains("Waiting") || serverInfo.MOTD.contains("Cup")) && (serverInfo.MaxPlayers - serverInfo.CurrentPlayers) >= slots) { SelectServer(player, serverInfo); return; } } } catch (Exception exception) { Logger.Instance.log(exception); exception.printStackTrace(); } UtilPlayer.message(player, F.main("Server Portal", "There are currently no joinable servers!")); } } @EventHandler public void checkQueuePrompts(UpdateEvent event) { if (event.getType() != UpdateType.SEC) return; /* for (final Player player : _queueManager.findPlayersNeedingPrompt()) { player.playSound(player.getLocation(), Sound.ENDERDRAGON_GROWL, 5f, 1f); Bukkit.getScheduler().runTaskLater(GetPlugin(), new Runnable() { public void run() { if (player.isOnline()) { _domShop.attemptShopOpen(player); } } }, 20); } */ } @EventHandler(priority = EventPriority.LOW) public void playerJoin(PlayerJoinEvent event) { event.getPlayer().getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.COMPASS.getId(), (byte)0, 1, ChatColor.GREEN + "Game Menu")); event.getPlayer().getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.WATCH.getId(), (byte)0, 1, ChatColor.GREEN + "Lobby Menu")); if (_clientManager.Get(event.getPlayer()).GetRank() == Rank.ALL) { _freeJoinTime.put(event.getPlayer().getName(), System.currentTimeMillis()); } } @EventHandler public void playerQuit(PlayerQuitEvent event) { _freeJoinTime.remove(event.getPlayer().getName()); } @EventHandler(priority = EventPriority.LOWEST) public void playerInteract(PlayerInteractEvent event) { if (event.getItem() != null && event.getItem().getType() == Material.COMPASS) { _quickShop.attemptShopOpen(event.getPlayer()); } else if (event.getItem() != null && event.getItem().getType() == Material.WATCH) { _lobbyShop.attemptShopOpen(event.getPlayer()); } } public Long getMillisecondsUntilPortal(Player player) { // Party party = _partyManager.GetParty(player); long timeLeft = 0; if (_freeJoinTime.containsKey(player.getName())) { timeLeft = (_freeJoinTime.get(player.getName()) - System.currentTimeMillis()) + FREE_PORTAL_TIMER; if (timeLeft <= 0) { _freeJoinTime.remove(player.getName()); timeLeft = 0; } } // if (party != null) // { // if (player.getName().equals(party.GetLeader())) // { // for (Player partyPlayer : party.GetPlayersOnline()) // { // if (!partyPlayer.equals(player)) // timeLeft = Math.max(timeLeft, getMillisecondsUntilPortal(partyPlayer)); // } // } // } return timeLeft; } public void RemoveServer(String serverName) { for (String key : _serverKeyInfoMap.keySet()) { _serverKeyInfoMap.get(key).remove(serverName); } _serverInfoMap.remove(serverName); } public void addServerGroup(String serverKey, String serverTag) { _serverKeyInfoMap.put(serverKey, new HashSet()); _serverKeyTagMap.put(serverTag, serverKey); } public void AddServerNpc(String serverNpcName, String serverTag) { addServerGroup(serverNpcName, serverTag); _serverNpcShopMap.put(serverNpcName, new ServerNpcShop(this, _clientManager, _donationManager, serverNpcName)); } public void RemoveServerNpc(String serverNpcName) { Set mappedServers = _serverKeyInfoMap.remove(serverNpcName); _serverNpcShopMap.remove(serverNpcName); if (mappedServers != null) { for (ServerInfo mappedServer : mappedServers) { boolean isMappedElseWhere = false; for (String key : _serverKeyInfoMap.keySet()) { for (ServerInfo value : _serverKeyInfoMap.get(key)) { if (value.Name.equalsIgnoreCase(mappedServer.Name)) { isMappedElseWhere = true; break; } } if (isMappedElseWhere) break; } if (!isMappedElseWhere) _serverInfoMap.remove(mappedServer.Name); } } } public Collection GetServerList(String serverNpcName) { return _serverKeyInfoMap.get(serverNpcName); } public Set GetAllServers() { return _serverInfoMap.keySet(); } public ServerInfo GetServerInfo(String serverName) { return _serverInfoMap.get(serverName); } public boolean HasServerNpc(String serverNpcName) { return _serverKeyInfoMap.containsKey(serverNpcName); } @EventHandler public void updatePages(UpdateEvent event) { if (event.getType() != UpdateType.FAST) return; _quickShop.UpdatePages(); for (ServerNpcShop shop : _serverNpcShopMap.values()) { shop.UpdatePages(); } } @EventHandler public void updateServers(UpdateEvent event) { if (event.getType() != UpdateType.SEC || (_retrieving && System.currentTimeMillis() - _lastRetrieve <= 5000)) return; _alternateUpdateFire = !_alternateUpdateFire; if (!_alternateUpdateFire) return; _retrieving = true; _statusManager.retrieveServerStatuses(new Callback>() { public void run(List serverStatusList) { for (ServerStatusData serverStatus : serverStatusList) { if (!_serverInfoMap.containsKey(serverStatus.Name)) { ServerInfo newServerInfo = new ServerInfo(); newServerInfo.Name = serverStatus.Name; _serverInfoMap.put(serverStatus.Name, newServerInfo); } String[] args = serverStatus.Motd.split("\\|"); String tag = (serverStatus.Name != null && serverStatus.Name.contains("-")) ? serverStatus.Name.split("-")[0] : "N/A"; ServerInfo serverInfo = _serverInfoMap.get(serverStatus.Name); serverInfo.MOTD = args.length > 0 ? args[0] : serverStatus.Motd; serverInfo.CurrentPlayers = serverStatus.Players; serverInfo.MaxPlayers = serverStatus.MaxPlayers; if (args.length > 1) serverInfo.ServerType = args[1]; if (args.length > 2) serverInfo.Game = args[2]; if (args.length > 3) serverInfo.Map = args[3]; _serverUpdate.put(serverStatus.Name, System.currentTimeMillis()); if (_serverKeyTagMap.containsKey(tag)) { _serverKeyInfoMap.get(_serverKeyTagMap.get(tag)).add(serverInfo); } } for (String name : _serverUpdate.keySet()) { if (_serverUpdate.get(name) != -1L && System.currentTimeMillis() - _serverUpdate.get(name) > 5000) { ServerInfo serverInfo = _serverInfoMap.get(name); serverInfo.MOTD = ChatColor.DARK_RED + "OFFLINE"; serverInfo.CurrentPlayers = 0; serverInfo.MaxPlayers = 0; _serverUpdate.put(name, -1L); } } // Reset _retrieving = false; _lastRetrieve = System.currentTimeMillis(); } }); } public void Help(Player caller, String message) { UtilPlayer.message(caller, F.main(_moduleName, "Commands List:")); UtilPlayer.message(caller, F.help("/servernpc create ", " is name of npc.", Rank.OWNER)); UtilPlayer.message(caller, F.help("/servernpc delete ", " is name of npc.", Rank.OWNER)); UtilPlayer.message(caller, F.help("/servernpc addserver | ", "Adds server.", Rank.OWNER)); UtilPlayer.message(caller, F.help("/servernpc removeserver ", "Removes server.", Rank.OWNER)); UtilPlayer.message(caller, F.help("/servernpc listnpcs", "Lists all server npcs.", Rank.OWNER)); UtilPlayer.message(caller, F.help("/servernpc listservers ", "Lists all servers.", Rank.OWNER)); UtilPlayer.message(caller, F.help("/servernpc listoffline", "Shows all servers offline.", Rank.OWNER)); if (message != null) UtilPlayer.message(caller, F.main(_moduleName, ChatColor.RED + message)); } public void Help(Player caller) { Help(caller, null); } public PartyManager getPartyManager() { return _partyManager; } public void SelectServer(org.bukkit.entity.Player player, ServerInfo serverInfo) { Party party = _partyManager.GetParty(player); if (party != null) { if (player.getName().equals(party.GetLeader())) { for (String name : party.GetPlayers()) { Player partyPlayer = UtilPlayer.searchExact(name); if (partyPlayer == null) continue; if (serverInfo.Name.contains("BETA")) { if (!_clientManager.Get(partyPlayer).GetRank().Has(Rank.ULTRA)) continue; } if (!_clientManager.Get(partyPlayer).GetRank().Has(Rank.MODERATOR) && serverInfo.CurrentPlayers >= serverInfo.MaxPlayers * 1.5) continue; if (_clientManager.Get(partyPlayer).GetRank().Has(Rank.ULTRA) || _donationManager.Get(partyPlayer.getName()).OwnsUnknownPackage(serverInfo.ServerType + " ULTRA")) continue; partyPlayer.leaveVehicle(); partyPlayer.eject(); _portal.SendPlayerToServer(partyPlayer, serverInfo.Name); } for (String name : party.GetPlayers()) { Player partyPlayer = UtilPlayer.searchExact(name); if (partyPlayer == null) continue; if (serverInfo.Name.contains("BETA")) { if (!_clientManager.Get(partyPlayer).GetRank().Has(Rank.ULTRA)) continue; } if (!_clientManager.Get(partyPlayer).GetRank().Has(Rank.MODERATOR) && serverInfo.CurrentPlayers >= serverInfo.MaxPlayers * 1.5) continue; if (_clientManager.Get(partyPlayer).GetRank().Has(Rank.ULTRA) || _donationManager.Get(partyPlayer.getName()).OwnsUnknownPackage(serverInfo.ServerType + " ULTRA")) { partyPlayer.leaveVehicle(); partyPlayer.eject(); _portal.SendPlayerToServer(partyPlayer, serverInfo.Name); } } } } else { player.leaveVehicle(); player.eject(); _portal.SendPlayerToServer(player, serverInfo.Name); } } public void ListServerNpcs(Player caller) { UtilPlayer.message(caller, F.main(GetName(), "Listing Server Npcs:")); for (String serverNpc : _serverKeyInfoMap.keySet()) { UtilPlayer.message(caller, F.main(GetName(), C.cYellow + serverNpc)); } } public void ListServers(Player caller, String serverNpcName) { UtilPlayer.message(caller, F.main(GetName(), "Listing Servers for '" + serverNpcName + "':")); for (ServerInfo serverNpc : _serverKeyInfoMap.get(serverNpcName)) { UtilPlayer.message(caller, F.main(GetName(), C.cYellow + serverNpc.Name + C.cWhite + " - " + serverNpc.MOTD + " " + serverNpc.CurrentPlayers + "/" + serverNpc.MaxPlayers)); } } public void ListOfflineServers(Player caller) { UtilPlayer.message(caller, F.main(GetName(), "Listing Offline Servers:")); for (ServerInfo serverNpc : _serverInfoMap.values()) { if (serverNpc.MOTD.equalsIgnoreCase(ChatColor.DARK_RED + "OFFLINE")) { UtilPlayer.message(caller, F.main(GetName(), C.cYellow + serverNpc.Name + C.cWhite + " - " + F.time(UtilTime.convertString(System.currentTimeMillis() - _serverUpdate.get(serverNpc.Name), 0, TimeUnit.FIT)))); } } } public void LoadServers() { _serverInfoMap.clear(); _serverUpdate.clear(); for (String npcName : _serverKeyInfoMap.keySet()) { _serverKeyInfoMap.get(npcName).clear(); } _serverKeyTagMap.clear(); FileInputStream fstream = null; BufferedReader br = null; HashSet npcNames = new HashSet(); try { File npcFile = new File("ServerManager.dat"); if (npcFile.exists()) { fstream = new FileInputStream(npcFile); br = new BufferedReader(new InputStreamReader(fstream)); String line = br.readLine(); while (line != null) { String serverNpcName = line.substring(0, line.indexOf('|')).trim(); String serverTag = line.substring(line.indexOf('|') + 1, line.indexOf('|', line.indexOf('|') + 1)).trim(); String[] locations = line.substring(line.indexOf('|', line.indexOf('|') + 1) + 1).trim().split(","); for (String location : locations) { _serverPortalLocations.put(ParseVector(location), serverNpcName); } if (!HasServerNpc(serverNpcName)) { AddServerNpc(serverNpcName, serverTag); } npcNames.add(serverNpcName); line = br.readLine(); } } } catch (Exception e) { Logger.Instance.log(e); System.out.println("ServerManager - Error parsing servers file : " + e.getMessage()); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (fstream != null) { try { fstream.close(); } catch (IOException e) { e.printStackTrace(); } } } for (String npcName : npcNames) { if (!_serverNpcShopMap.containsKey(npcName)) _serverNpcShopMap.remove(npcName); if (!_serverKeyInfoMap.containsKey(npcName)) _serverKeyInfoMap.remove(npcName); } } public int GetRequiredSlots(Player player, String serverType) { int slots = 0; Party party = _partyManager.GetParty(player); if (party != null) { if (player.getName().equals(party.GetLeader())) { for (String name : party.GetPlayers()) { Player partyPlayer = UtilPlayer.searchExact(name); if (partyPlayer == null) continue; if (_clientManager.Get(partyPlayer).GetRank().Has(Rank.ULTRA) || _donationManager.Get(partyPlayer.getName()).OwnsUnknownPackage(serverType + " ULTRA")) continue; slots++; } } } else { if (!_clientManager.Get(player).GetRank().Has(Rank.ULTRA) && !_donationManager.Get(player.getName()).OwnsUnknownPackage(serverType + " ULTRA")) slots++; } return slots; } public ServerNpcShop getMixedArcadeShop() { return _serverNpcShopMap.get("Mixed Arcade"); } public ServerNpcShop getSuperSmashMobsShop() { return _serverNpcShopMap.get("Super Smash Mobs"); } @SuppressWarnings("rawtypes") public ShopBase getDominateShop() { return _serverNpcShopMap.get("Dominate"); } public ServerNpcShop getBridgesShop() { return _serverNpcShopMap.get("The Bridges"); } public ServerNpcShop getSurvivalGamesShop() { return _serverNpcShopMap.get("Survival Games"); } public ServerNpcShop getBlockHuntShop() { return _serverNpcShopMap.get("Block Hunt"); } private Vector ParseVector(String vectorString) { Vector vector = new Vector(); String [] parts = vectorString.trim().split(" "); vector.setX(Double.parseDouble(parts[0])); vector.setY(Double.parseDouble(parts[1])); vector.setZ(Double.parseDouble(parts[2])); return vector; } public ServerStatusManager getStatusManager() { return _statusManager; } public ShopBase getCastleSiegeShop() { return _serverNpcShopMap.get("Castle Siege"); } }