Add pages for Team games and removal of old system

This commit is contained in:
Sam 2018-07-30 17:46:06 +01:00 committed by Alexander Meech
parent 27be29145b
commit f9504a9e4c
22 changed files with 389 additions and 881 deletions

View File

@ -83,9 +83,10 @@ public class GameInfo
public enum GameDisplayStatus
{
WAITING,
VOTING,
// Sorted by priority
STARTING,
VOTING,
WAITING,
IN_PROGRESS,
CLOSING
}

View File

@ -1,58 +0,0 @@
package mineplex.core.locations;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
/**
* This class controls all "hard coded" locations that will be the same throughout the entire server
* regardless of whether or not it is on hub
*/
public class LocationConstants
{
private static final int CHEST_X = 31;
private static final int CHEST_Z = 23;
/**
* The number to be added to either the X or the Z for chest reset locations
*/
private static final int CHEST_ADD = 5;
public static final World WORLD = Bukkit.getWorld("world");
public static final Location HUB_SPAWN = new Location(WORLD, 0, 77, -32);
public static final Location[] CHEST_LOCATIONS = {
new Location(WORLD, 34, 72, -15),
new Location(WORLD, 26, 72, -35),
new Location(WORLD, -23, 72, -31),
new Location(WORLD, -34, 72, -15)
};
//new Location(world, -25.5, 73, 19.5), new Location(world, -35.5, 69, 1.5)
public static final Location FOUNTAIN_SCHEMATIC = new Location(WORLD, -41.5, 68, 5.5);
public static final Location FOUNTAIN_LOCATION = new Location(WORLD, -30.5, 72, 28.5);
public static Location getResetLocation(Location chestLocation)
{
int x = chestLocation.getBlockX();
int z = chestLocation.getBlockZ();
int absX = Math.abs(x);
int absZ = Math.abs(z);
if (absX == CHEST_X)
{
return chestLocation.clone().add(CHEST_ADD, 0, 0);
}
if (absZ == CHEST_Z)
{
return chestLocation.clone().add(0, 0, CHEST_ADD);
}
return chestLocation.clone().add(CHEST_ADD, 0, CHEST_ADD);
}
}

View File

@ -1,6 +1,5 @@
package mineplex.core.party;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@ -101,7 +100,7 @@ public class PartyManager extends MiniPlugin
_inviteManager = new PartyInviteManager(this);
_joinManager = new PartyJoinManager(this);
_region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_region = UtilServer.getRegion();
_messageManager = require(MessageManager.class);

View File

@ -1,387 +0,0 @@
package mineplex.hub.modules;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.Entity;
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.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.BlockVector;
import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.permissions.Permission;
import mineplex.core.account.permissions.PermissionGroup;
import mineplex.core.achievement.Achievement;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Pair;
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.util.C;
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.UtilTextMiddle;
import mineplex.core.creature.Creature;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.utils.UtilVariant;
import mineplex.hub.server.ServerManager;
@ReflectivelyCreateMiniPlugin
public class AlienInvasion extends MiniPlugin
{
public enum Perm implements Permission
{
TOGGLE_ANIMATION_COMMAND,
}
private static final String SCHEMATIC_PATH = ".." + File.separator + ".." + File.separator + "update" + File.separator + "files" + File.separator + "UFO.schematic";
private static final int[][] UFO_SPAWNS =
{
{
0, 81, -14
},
{
15, 91, -11
},
{
-10, 94, 5
},
{
-25, 97, -26
},
{
-17, 94, -47
},
{
20, 95, -55,
},
{
45, 106, -23
},
{
50, 110, 16
},
{
-33, 125, 5
},
{
30, 102, 10
}
};
/**
* Bob Ross is not an alien
*/
private static final String[] ALIEN_SPEAK =
{
"Every day is a good day when you paint",
"Beat the devil out of it",
"Happy little clouds",
"Happy little trees",
"I believe",
"I wonder if anyone can see these messages",
"Get involved",
"Ruff",
"Hey you, I see you using the game log output. You should totally go to Moppletop's wall on enjin and say HOI"
};
private static final ItemStack HELMET = new ItemStack(Material.GLASS);
private final BlockRestore _restore;
private final Creature _creature;
private final StatsManager _stats;
private final ServerManager _serverManager;
private final World _world;
private Schematic _schematic;
private boolean _active;
private int _lastUFOIndex;
private Location _beam;
private final Set<Block> _ufoBlocks;
private final Set<Block> _beaconBlocks;
private final Set<LivingEntity> _aliens;
public AlienInvasion()
{
super("Alien Invasion");
_restore = require(BlockRestore.class);
_creature = require(Creature.class);
_stats = require(StatsManager.class);
_serverManager = Managers.get(ServerManager.class);
_world = Bukkit.getWorld("world");
_ufoBlocks = new HashSet<>(200);
_beaconBlocks = new HashSet<>();
_aliens = new HashSet<>();
addCommand(new CommandBase<AlienInvasion>(this, Perm.TOGGLE_ANIMATION_COMMAND, "alien-animation-start")
{
@Override
public void Execute(Player caller, String[] args)
{
startAnimation();
}
});
addCommand(new CommandBase<AlienInvasion>(this, Perm.TOGGLE_ANIMATION_COMMAND, "alien-animation-stop")
{
@Override
public void Execute(Player caller, String[] args)
{
stopAnimation();
}
});
startAnimation();
generatePermissions();
}
private void generatePermissions()
{
PermissionGroup.ADMIN.setPermission(Perm.TOGGLE_ANIMATION_COMMAND, true, true);
}
public void startAnimation()
{
if (_active)
{
return;
}
try
{
_schematic = UtilSchematic.loadSchematic(new File(SCHEMATIC_PATH));
}
catch (IOException e)
{
e.printStackTrace();
return;
}
_lastUFOIndex = 0;
_active = true;
_world.setTime(18000);
for (Player player : Bukkit.getOnlinePlayers())
{
player.playSound(player.getLocation(), Sound.ENDERDRAGON_DEATH, 1, 0.5F);
}
UtilTextMiddle.display(C.cGreen + "Aliens Are Invading", "Defend the Hub!");
}
public void sendPlayerToInstance(Player player)
{
_serverManager.selectServer(player, "UFO");
}
public void stopAnimation()
{
if (!_active)
{
return;
}
_active = false;
for (Block block : _ufoBlocks)
{
block.setType(Material.AIR);
}
_ufoBlocks.clear();
for (LivingEntity entity : _aliens)
{
entity.remove();
}
_aliens.clear();
for (Block block : _beaconBlocks)
{
_restore.restore(block);
}
_beaconBlocks.clear();
_world.setTime(6000);
}
@EventHandler
public void updateUFOSpwawn(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC || !_active || _lastUFOIndex == UFO_SPAWNS.length)
{
return;
}
int[] cords = UFO_SPAWNS[_lastUFOIndex];
Location location = new Location(_world, cords[0], cords[1], cords[2]);
location.subtract(5, 0, 5);
UtilParticle.PlayParticleToAll(ParticleType.FIREWORKS_SPARK, location, 5F, 5F, 5F, 1, 50, ViewDist.LONG);
SchematicData data = _schematic.paste(location, true, false, false);
Location beam = data.getDataLocationMap().getIronLocations(DyeColor.LIME).get(0);
for (BlockVector vector : data.getBlocks())
{
Location block = location.add(vector);
_ufoBlocks.add(block.getBlock());
location.subtract(vector);
}
if (_lastUFOIndex == 0)
{
// Spawn a beacon
Block ground = beam.getBlock();
while (ground.getType() == Material.AIR)
{
ground = ground.getRelative(BlockFace.DOWN);
}
ground = ground.getRelative(BlockFace.UP);
_beam = ground.getLocation();
for (Pair<Location, Pair<Material, Byte>> pair : UtilBlock.getBeaconBlocks(ground.getLocation(), (byte) 5))
{
Block block = pair.getLeft().getBlock();
_restore.add(block, pair.getRight().getLeft().getId(), pair.getRight().getRight(), Long.MAX_VALUE);
_beaconBlocks.add(block);
}
}
_lastUFOIndex++;
}
@EventHandler
public void updateAlienSpawn(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST || !_active || _beam == null || _aliens.size() > 20)
{
return;
}
_creature.SetForce(true);
Location random = UtilAlg.getRandomLocation(_beam.clone().add(0, 5, 0), 30, 4, 30);
random.setYaw(UtilMath.r(180));
Skeleton skeleton = UtilVariant.spawnWitherSkeleton(random);
skeleton.getEquipment().setHelmet(HELMET);
skeleton.setCustomNameVisible(true);
skeleton.setCustomName(C.cGreenB + "Alien");
UtilEnt.vegetate(skeleton);
_aliens.add(skeleton);
_creature.SetForce(false);
}
@EventHandler
public void updateSendToInstance(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC || !_active || _beam == null)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
if (UtilMath.offsetSquared(player.getLocation(), _beam) > 9)
{
continue;
}
sendPlayerToInstance(player);
}
}
@EventHandler
public void interactAlien(EntityDamageByEntityEvent event)
{
Entity entity = event.getEntity();
Entity damager = event.getDamager();
if (!_aliens.contains(entity))
{
return;
}
if (damager instanceof Player)
{
Player player = (Player) damager;
sendAlienSpeak(player);
}
else if (damager instanceof EnderPearl)
{
((LivingEntity) entity).setHealth(0);
_aliens.remove(entity);
Projectile projectile = (Projectile) damager;
Player shooter = (Player) projectile.getShooter();
shooter.playSound(shooter.getLocation(), Sound.NOTE_PLING, 1, 1.8F);
_stats.incrementStat(shooter, Achievement.GLOBAL_ALIEN_INVASION.getStats()[0], 1);
}
}
@EventHandler
public void interactAlien(PlayerInteractAtEntityEvent event)
{
Player player = event.getPlayer();
Entity entity = event.getRightClicked();
if (!_aliens.contains(entity))
{
return;
}
sendAlienSpeak(player);
}
private void sendAlienSpeak(Player player)
{
player.sendMessage(C.cGreen + C.Scramble + ALIEN_SPEAK[UtilMath.r(ALIEN_SPEAK.length)]);
}
}

View File

@ -1,95 +0,0 @@
package mineplex.hub.modules;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.UtilTime;
import mineplex.core.newnpc.event.NPCInteractEvent;
import mineplex.core.npc.event.NpcInteractEntityEvent;
import mineplex.core.portal.Intent;
import mineplex.core.portal.Portal;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.hub.server.ServerInfo;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.servers.ServerManager;
// A hacky mess. Did not have time before release to solve this properly. soon.
// Essentially a copy/paste from the clans hub server load/send mechanism
public class TemporaryGemHuntersServerSender extends MiniPlugin
{
private static final int SERVER_RELOAD_INTERVAL = 5000;
private final Portal _portal;
private final Map<MinecraftServer,ServerInfo> _servers = new ConcurrentHashMap<>();
private long _lastLoaded = 0;
private boolean _loading;
public TemporaryGemHuntersServerSender(Portal portal)
{
super("Gem Hunters Server Sender");
_portal = portal;
}
@EventHandler
public void reloadServers(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC || _loading || !UtilTime.elapsed(_lastLoaded, SERVER_RELOAD_INTERVAL))
{
return;
}
_loading = true;
runAsync(() ->
{
reload();
runSync(() ->
{
_lastLoaded = System.currentTimeMillis();
_loading = false;
});
});
}
public void reload()
{
_servers.clear();
Region region = getPlugin().getConfig().getBoolean("serverstatus.us") ? Region.US : Region.EU;
for (MinecraftServer server : ServerManager.getServerRepository(region).getServerStatusesByPrefix("GH-"))
{
ServerInfo info = new ServerInfo();
info.Name = server.getName();
info.MOTD = server.getMotd();
info.CurrentPlayers = server.getPlayerCount();
info.MaxPlayers = server.getMaxPlayerCount();
_servers.put(server, info);
}
}
@EventHandler
public void onUseNPC(NPCInteractEvent event)
{
if (event.getNpc().getMetadata().equals("GAME_Gem Hunters"))
{
java.util.Optional<ServerInfo> info = _servers.entrySet().stream()
// Ignore the type noise here; it's temporary
.sorted(Comparator.<Map.Entry<MinecraftServer,ServerInfo>>comparingInt(entry -> entry.getKey().getPlayerCount()).<Map.Entry<MinecraftServer,ServerInfo>>reversed())
.filter(entry -> entry.getKey().getPlayerCount() < entry.getKey().getMaxPlayerCount() - 5)
.map(Map.Entry::getValue)
.findFirst();
if (info.isPresent())
{
_portal.sendPlayerToServer(event.getPlayer(), info.get().Name, Intent.PLAYER_REQUEST);
}
else
{
event.getPlayer().sendMessage(ChatColor.RED + "All servers are full; please try again in a moment!");
}
}
}
}

View File

@ -43,9 +43,10 @@ public class GameServer
}
}
public void setServer(MinecraftServer server)
public void updateStatus(MinecraftServer server, GameInfo info)
{
_server = server;
_info = info;
_lastUpdate = System.currentTimeMillis();
}
@ -64,11 +65,6 @@ public class GameServer
return _number;
}
void setInfo(GameInfo info)
{
_info = info;
}
public GameInfo getInfo()
{
return _info;

View File

@ -1,14 +0,0 @@
package mineplex.hub.server;
import java.util.Comparator;
public class LobbySorter implements Comparator<ServerInfo>
{
public int compare(ServerInfo a, ServerInfo b)
{
if (Integer.parseInt(a.Name.split("-")[1]) < Integer.parseInt(b.Name.split("-")[1]))
return -1;
return 1;
}
}

View File

@ -1,28 +0,0 @@
package mineplex.hub.server;
import mineplex.core.account.permissions.PermissionGroup;
import mineplex.core.common.util.UtilServer;
import mineplex.serverdata.data.MinecraftServer;
public class ServerInfo
{
public String Name;
public String MOTD = "Retrieving status";
public int CurrentPlayers = 0;
public int MaxPlayers = 0;
public String Map;
public String ServerType;
public String Game;
public PermissionGroup HostRank = null;
public MinecraftServer Server;
public int getAvailableSlots()
{
return MaxPlayers - CurrentPlayers;
}
public boolean isDevServer()
{
return UtilServer.isDevServer(Name);
}
}

View File

@ -8,7 +8,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@ -43,10 +42,13 @@ import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
import mineplex.core.game.status.GameInfo;
import mineplex.core.game.status.GameInfo.GameJoinStatus;
import mineplex.core.newnpc.NPC;
import mineplex.core.newnpc.NewNPCManager;
import mineplex.core.newnpc.StoredNPC;
import mineplex.core.newnpc.event.NPCInteractEvent;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.core.party.event.PartySelectServerEvent;
import mineplex.core.personalServer.PersonalServerManager;
import mineplex.core.portal.Intent;
@ -61,9 +63,9 @@ import mineplex.core.twofactor.TwoFactorAuth;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.hub.HubManager;
import mineplex.hub.server.newui.ServerSelectionShop;
import mineplex.hub.server.ui.LobbyShop;
import mineplex.hub.server.ui.QuickShop;
import mineplex.hub.server.ui.game.QuickShop;
import mineplex.hub.server.ui.lobby.LobbyShop;
import mineplex.hub.server.ui.server.ServerSelectionShop;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.data.ServerGroup;
@ -76,11 +78,7 @@ public class ServerManager extends MiniPlugin
FEATURE_SERVER,
}
private static final Random RANDOM = new Random();
private static final int TOP_SERVERS = 3; // The number of top contending servers for auto-joining games
private static final int MIN_SLOTS_REQUIRED = 12; // The number of slots the max server must have for auto-join
private static final long SELECT_SERVER_COOLDOWN = TimeUnit.SECONDS.toMillis(3);
private static final long SELECT_SERVER_COOLDOWN = TimeUnit.SECONDS.toMillis(2);
private static final long SERVER_TIMEOUT = TimeUnit.SECONDS.toMillis(5);
private static final String MPS_PREFIX = "MPS";
@ -91,6 +89,7 @@ public class ServerManager extends MiniPlugin
private final HubManager _hubManager;
private final BoosterManager _boosterManager;
private final TwoFactorAuth _twofactor;
private final PartyManager _partyManager;
private final PreferencesManager _preferencesManager;
private final AchievementManager _achievementManager;
private final TreasureManager _treasureManager;
@ -141,7 +140,7 @@ public class ServerManager extends MiniPlugin
private ServerManager()
{
super("Server Manager");
super("Matchmaker");
_clientManager = require(CoreClientManager.class);
_donationManager = require(DonationManager.class);
@ -150,6 +149,7 @@ public class ServerManager extends MiniPlugin
_hubManager = require(HubManager.class);
_boosterManager = require(BoosterManager.class);
_twofactor = require(TwoFactorAuth.class);
_partyManager = require(PartyManager.class);
_preferencesManager = require(PreferencesManager.class);
_achievementManager = require(AchievementManager.class);
_treasureManager = require(TreasureManager.class);
@ -259,15 +259,18 @@ public class ServerManager extends MiniPlugin
if (npcName.contains("Clans"))
{
ServerInfo serverInfo = getBestServer(player, "ClansHub");
ServerGroup serverGroup = _serverGroupsByName.get("Clans");
if (serverInfo == null)
if (serverGroup == null)
{
player.sendMessage(F.main(_moduleName, "Sorry, there are no available " + F.name("Clans Hub") + " to take you too at this moment."));
player.sendMessage(F.main(getName(), "Oh dear, this isn't good. Looks like Clans isn't a registered group."));
return;
}
selectServer(player, serverInfo);
if (!selectBest(player, serverGroup))
{
player.sendMessage(F.main(getName(), "Sorry I was unable to find you a good server to send you to."));
}
return;
}
@ -337,7 +340,13 @@ public class ServerManager extends MiniPlugin
}
}
public void addServerGroup(ServerGroup serverGroup)
@EventHandler
public void onClickCompassPartyIcon(PartySelectServerEvent event)
{
_quickShop.attemptShopOpen(event.getPlayer());
}
private void addServerGroup(ServerGroup serverGroup)
{
_serverGroupsByName.put(serverGroup.getName(), serverGroup);
@ -347,7 +356,7 @@ public class ServerManager extends MiniPlugin
}
}
public void openServerShop(Player player, String npcName)
private void openServerShop(Player player, String npcName)
{
ServerGroup serverGroup = _serverGroupsByNPCName.get(npcName);
@ -357,22 +366,18 @@ public class ServerManager extends MiniPlugin
}
}
@EventHandler
public void onClickCompassPartyIcon(PartySelectServerEvent event)
{
_quickShop.attemptShopOpen(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void updatePages(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
if (event.getType() == UpdateType.SEC)
{
return;
_quickShop.updatePages();
_serverShop.updatePages();
}
else if (event.getType() == UpdateType.SLOW)
{
_lobbyShop.updatePages();
}
_quickShop.UpdatePages();
_serverShop.updatePages();
}
@EventHandler
@ -428,7 +433,6 @@ public class ServerManager extends MiniPlugin
Map<String, GameServer> servers = _gameServers.computeIfAbsent(serverGroup.getPrefix(), k -> new HashMap<>());
GameServer gameServer = servers.computeIfAbsent(serverStatus.getName(), k -> new GameServer(serverStatus));
gameServer.setServer(serverStatus);
GameInfo gameInfo;
try
@ -441,7 +445,7 @@ public class ServerManager extends MiniPlugin
gameInfo = new GameInfo();
}
gameServer.setInfo(gameInfo);
gameServer.updateStatus(serverStatus, gameInfo);
String prefix = serverGroup.getPrefix();
@ -466,99 +470,70 @@ public class ServerManager extends MiniPlugin
});
}
public void selectServer(Player player, ServerInfo serverInfo)
public boolean selectServer(Player player, GameServer server)
{
if (!Recharge.Instance.use(player, getName(), SELECT_SERVER_COOLDOWN, false, false))
{
return false;
}
player.leaveVehicle();
player.eject();
_portal.sendPlayerToServer(player, serverInfo.Name, Intent.PLAYER_REQUEST);
_portal.sendPlayerToServer(player, server.getServer().getName(), Intent.PLAYER_REQUEST);
return true;
}
/**
* Select a {@code serverType} for a {@code player} that wishes to automatically join the best server
* available for that server type.
*
* @param player - the player hoping to select a server
* @param serverType - the name of the type of server to be joined
*/
public void selectServer(Player player, String serverType)
public boolean selectBest(Player player, ServerGroup serverGroup)
{
if (!Recharge.Instance.use(player, "Select Server", SELECT_SERVER_COOLDOWN, false, false))
Collection<GameServer> servers = getServers(serverGroup.getPrefix());
int required = getRequiredSlots(player);
servers.removeIf(server ->
{
return;
}
MinecraftServer serverStatus = server.getServer();
GameInfo info = server.getInfo();
ServerInfo bestServer = getBestServer(player, serverType);
if (bestServer != null)
{
selectServer(player, bestServer);
}
}
/**
* @param serverKey - the type of server that should be fetched
* @return the best server that a new player should join according to a {@code serverType} constraint.
*/
public ServerInfo getBestServer(Player player, String serverKey)
{
Collection<ServerInfo> serverList = null;
if (serverList == null)
{
return null;
}
List<ServerInfo> servers = new ArrayList<>(serverList);
servers = fetchOpenServers(player, servers, servers.size()); // Removes all full servers from list
servers.sort((o1, o2) -> o2.CurrentPlayers - o1.CurrentPlayers);
int count = Math.min(servers.size(), TOP_SERVERS);
if (count > 0)
{
ServerInfo largestServer = servers.get(0);
if (largestServer.getAvailableSlots() >= MIN_SLOTS_REQUIRED || largestServer.MaxPlayers > 40)
if (server.isDevServer() || info.getJoinable() != GameJoinStatus.OPEN || serverStatus.getMaxPlayerCount() - serverStatus.getPlayerCount() <= required)
{
return largestServer;
return true;
}
else
switch (info.getStatus())
{
return servers.get(RANDOM.nextInt(count));
case WAITING:
case VOTING:
return false;
case STARTING:
// If the game is about to start, ignore it. The player probably won't make it in time.
return info.getTimer() < 6;
default:
return true;
}
}
});
return null;
}
public List<ServerInfo> fetchOpenServers(Player player, List<ServerInfo> servers, int count)
{
List<ServerInfo> results = new ArrayList<>();
int requiredSlots = (servers.size() > 0) ? getRequiredSlots(player, servers.get(0).ServerType) : 0;
for (ServerInfo server : servers)
if (servers.isEmpty())
{
if (isInProgress(server))
continue;
if (server.isDevServer())
continue;
if (results.size() >= count) break;
if (server.getAvailableSlots() > requiredSlots)
{
results.add(server);
}
return false;
}
return results;
List<GameServer> serversList = new ArrayList<>(servers);
serversList.sort((o1, o2) -> o2.getServer().getPlayerCount() - o1.getServer().getPlayerCount());
return selectServer(player, serversList.get(0));
}
private boolean isInProgress(ServerInfo serverInfo)
private int getRequiredSlots(Player player)
{
return serverInfo.MOTD.contains("Progress") || serverInfo.MOTD.contains("Restarting");
int required = 1;
Party party = _partyManager.getPartyByPlayer(player);
if (party != null)
{
required = party.getSize();
}
return required;
}
public Collection<GameServer> getServers(String prefix)
@ -567,6 +542,14 @@ public class ServerManager extends MiniPlugin
return servers == null ? Collections.emptyList() : servers.values();
}
public ServerGroup getServerGroupByPrefix(String prefix)
{
return _serverGroupsByName.values().stream()
.filter(serverGroup -> serverGroup.getPrefix().equals(prefix))
.findFirst()
.orElse(null);
}
private void loadServers()
{
_serverGroupsByName.clear();
@ -577,26 +560,11 @@ public class ServerManager extends MiniPlugin
addServerGroup(new ServerGroup("MPS", "Mineplex Player Servers", MPS_PREFIX));
}
public int getRequiredSlots(Player player, String serverType)
{
int slots = 0;
if (!_clientManager.Get(player).hasPermission(Perm.JOIN_FULL) && !_donationManager.Get(player).ownsUnknownSalesPackage(serverType + " ULTRA"))
slots++;
return slots;
}
public int getGroupTagPlayerCount(String tag)
{
return _playersPlaying.getOrDefault(tag, 0);
}
public ServerStatusManager getStatusManager()
{
return _statusManager;
}
public HubManager getHubManager()
{
return _hubManager;
@ -641,4 +609,9 @@ public class ServerManager extends MiniPlugin
{
return _titles;
}
public QuickShop getQuickShop()
{
return _quickShop;
}
}

View File

@ -1,90 +0,0 @@
package mineplex.hub.server;
import java.awt.Color;
import java.util.Comparator;
import org.bukkit.ChatColor;
public class ServerSorter implements Comparator<ServerInfo>
{
private int _requiredSlots;
public ServerSorter(int slots)
{
_requiredSlots = slots;
}
public int compare(ServerInfo a, ServerInfo b)
{
if ((b.MOTD.contains("Restarting")))
return -1;
if ((a.MOTD.contains("Restarting")))
return 1;
if ((a.MOTD.contains("Recruiting") || a.MOTD.contains("Waiting") || a.MOTD.contains("Starting") || a.MOTD.contains("Cup")) && !b.MOTD.contains("Recruiting") && !b.MOTD.contains("Waiting") && !b.MOTD.contains("Starting") && !b.MOTD.contains("Cup"))
return -1;
if ((b.MOTD.contains("Recruiting") || b.MOTD.contains("Waiting") || b.MOTD.contains("Starting") || b.MOTD.contains("Cup")) && !a.MOTD.contains("Recruiting") && !a.MOTD.contains("Waiting") && !a.MOTD.contains("Starting") && !a.MOTD.contains("Cup"))
return 1;
if (a.MOTD.contains("Generating") && b.MOTD.contains("Generating"))
{
try
{
String aTime = ChatColor.stripColor(a.MOTD.substring(a.MOTD.indexOf("(") + 1, a.MOTD.indexOf(")")));
String bTime = ChatColor.stripColor(b.MOTD.substring(b.MOTD.indexOf("(") + 1, b.MOTD.indexOf(")")));
int timeOfA = (int)Double.parseDouble(aTime.split(" ")[0]) * (aTime.contains("Minute") ? 60 : 1);
int timeOfB = (int)Double.parseDouble(bTime.split(" ")[0]) * (bTime.contains("Minute") ? 60 : 1);
if (timeOfA < timeOfB)
return -1;
else if (timeOfB < timeOfA)
return 1;
else
return 0;
}
catch (Exception exception)
{
exception.printStackTrace();
return 0;
}
}
if (a.Name.contains("Clans") && b.Name.contains("Clans"))
{
if (Integer.parseInt(a.Name.split("-")[1]) < Integer.parseInt(b.Name.split("-")[1]))
return -1;
else if (Integer.parseInt(a.Name.split("-")[1]) > Integer.parseInt(b.Name.split("-")[1]))
return 1;
}
if (a.MaxPlayers - a.CurrentPlayers < _requiredSlots && b.MaxPlayers - b.CurrentPlayers >= _requiredSlots)
return -1;
if (b.MaxPlayers - b.CurrentPlayers < _requiredSlots && a.MaxPlayers - a.CurrentPlayers >= _requiredSlots)
return 1;
if (a.CurrentPlayers > b.CurrentPlayers)
return -1;
if (b.CurrentPlayers > a.CurrentPlayers)
return 1;
boolean isDevServerA = a.isDevServer();
boolean isDevServerB = b.isDevServer();
int serverIdA = Integer.parseInt(a.Name.substring(a.Name.lastIndexOf('-') + 1));
int serverIdB = Integer.parseInt(b.Name.substring(b.Name.lastIndexOf('-') + 1));
if (isDevServerA && isDevServerB)
return Integer.compare(serverIdA, serverIdB);
else if (isDevServerA)
return -1;
else if (isDevServerB)
return 1;
else
return Integer.compare(serverIdA, serverIdB);
}
}

View File

@ -1,35 +0,0 @@
package mineplex.hub.server.newui;
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.hub.server.ServerManager;
import mineplex.serverdata.data.ServerGroup;
public class ServerSelectionShop extends ShopBase<ServerManager>
{
public ServerSelectionShop(ServerManager plugin, CoreClientManager clientManager, DonationManager donationManager, String name)
{
super(plugin, clientManager, donationManager, name);
}
@Override
protected ShopPageBase<ServerManager, ? extends ShopBase<ServerManager>> buildPagesFor(Player player)
{
return null;
}
public void openServerPage(Player player, ServerGroup group)
{
openPageForPlayer(player, new ServerSelectionPage(getPlugin(), this, getClientManager(), getDonationManager(), group, player));
}
public void updatePages()
{
getPageMap().values().forEach(ShopPageBase::refresh);
}
}

View File

@ -1,4 +1,4 @@
package mineplex.hub.server.ui;
package mineplex.hub.server.ui.game;
import org.bukkit.entity.Player;
@ -9,6 +9,7 @@ import mineplex.hub.server.ServerManager;
public class QuickShop extends ShopBase<ServerManager>
{
public QuickShop(ServerManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager, String name)
{
super(plugin, clientManager, donationManager, name);
@ -20,11 +21,9 @@ public class QuickShop extends ShopBase<ServerManager>
return new ServerGameMenu(getPlugin(), this, getClientManager(), getDonationManager(), "Quick Compass", player);
}
public void UpdatePages()
public void updatePages()
{
getPlayerPageMap().values().stream().filter(page -> page instanceof ServerGameMenu).forEach(page ->
{
((ServerGameMenu) page).Update();
});
getPageMap().values().forEach(ShopPageBase::refresh);
}
}

View File

@ -1,4 +1,4 @@
package mineplex.hub.server.ui;
package mineplex.hub.server.ui.game;
import java.util.Arrays;
@ -82,8 +82,7 @@ public class ServerGameMenu extends ShopPageBase<ServerManager, QuickShop>
.filter(achievement -> achievementManager.get(stats, achievement).getLevel() >= achievement.getMaxLevel())
.count();
GameDisplay bestGame = Arrays.stream(GameDisplay.values())
.sorted((o1, o2) -> (int) (stats.getStat(o2.getName() + ".Wins") - stats.getStat(o1.getName() + ".Wins")))
.findFirst()
.min((o1, o2) -> (int) (stats.getStat(o2.getName() + ".Wins") - stats.getStat(o1.getName() + ".Wins")))
.orElse(null);
Track track = getPlugin().getTitles().getActiveTrack(getPlayer());
@ -409,9 +408,4 @@ public class ServerGameMenu extends ShopPageBase<ServerManager, QuickShop>
}
}
}
public void Update()
{
buildPage();
}
}

View File

@ -1,4 +1,4 @@
package mineplex.hub.server.ui;
package mineplex.hub.server.ui.lobby;
import org.bukkit.entity.Player;

View File

@ -1,14 +1,11 @@
package mineplex.hub.server.ui;
package mineplex.hub.server.ui.lobby;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.hub.server.ServerManager;
public class LobbyShop extends ShopBase<ServerManager>
@ -25,14 +22,8 @@ public class LobbyShop extends ShopBase<ServerManager>
return new LobbyMenu(getPlugin(), this, getClientManager(), getDonationManager(), "Lobby Selector", player, "Lobby");
}
@EventHandler
public void update(UpdateEvent event)
public void updatePages()
{
if (event.getType() != UpdateType.SLOW)
{
return;
}
getPageMap().values().forEach(ShopPageBase::refresh);
}
}

View File

@ -0,0 +1,46 @@
package mineplex.hub.server.ui.server;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.hub.server.ServerManager;
import mineplex.serverdata.data.ServerGroup;
public class CakeWarsServerSelectionPage extends ServerModeSelectionPage
{
public CakeWarsServerSelectionPage(ServerManager plugin, ServerSelectionShop shop, CoreClientManager clientManager, DonationManager donationManager, ServerGroup serverGroup, Player player)
{
super(plugin, shop, clientManager, donationManager, serverGroup, player);
}
@Override
protected void buildPage()
{
super.buildPage();
addButton(11, new ItemBuilder(Material.CAKE)
.setTitle(C.cYellowB + "Cake Wars " + C.cGoldB + "Standard")
.addLore(
"",
"4v4v4v4!",
"",
CLICK_TO_PLAY
)
.build(), getButtonFor("CW4", "Cake Wars Standard"));
addButton(15, new ItemBuilder(Material.SUGAR)
.setTitle(C.cYellowB + "Cake Wars " + C.cGoldB + "Duos")
.addLore(
"",
"8 Teams of 2!",
"",
CLICK_TO_PLAY
)
.build(), getButtonFor("CW2", "Cake Wars Duos"));
}
}

View File

@ -0,0 +1,46 @@
package mineplex.hub.server.ui.server;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.hub.server.ServerManager;
import mineplex.serverdata.data.ServerGroup;
public class ChampionsServerSelectionPage extends ServerModeSelectionPage
{
public ChampionsServerSelectionPage(ServerManager plugin, ServerSelectionShop shop, CoreClientManager clientManager, DonationManager donationManager, ServerGroup serverGroup, Player player)
{
super(plugin, shop, clientManager, donationManager, serverGroup, player);
}
@Override
protected void buildPage()
{
super.buildPage();
addButton(11, new ItemBuilder(Material.BEACON)
.setTitle(C.cYellowB + "Champions " + C.cGoldB + "Dominate")
.addLore(
"",
"TODO",
"",
CLICK_TO_PLAY
)
.build(), getButtonFor("DOM", "Dominate"));
addButton(15, new ItemBuilder(Material.BANNER)
.setTitle(C.cYellowB + "Champions " + C.cGoldB + "CTF")
.addLore(
"",
"TODO",
"",
CLICK_TO_PLAY
)
.build(), getButtonFor("CTF", "Capture The Flag"));
}
}

View File

@ -0,0 +1,43 @@
package mineplex.hub.server.ui.server;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.hub.server.ServerManager;
import mineplex.serverdata.data.ServerGroup;
public class ServerModeSelectionPage extends ShopPageBase<ServerManager, ServerSelectionShop>
{
protected static final String CLICK_TO_PLAY = C.cDGreen + "►► " + C.cGreen + "Click to Play!";
protected final ServerGroup _serverGroup;
ServerModeSelectionPage(ServerManager plugin, ServerSelectionShop shop, CoreClientManager clientManager, DonationManager donationManager, ServerGroup serverGroup, Player player)
{
super(plugin, shop, clientManager, donationManager, serverGroup.getServerNpcName(), player, 27);
_serverGroup = serverGroup;
buildPage();
}
@Override
protected void buildPage()
{
addButton(4, new ItemBuilder(Material.BED)
.setTitle(C.cGreen + "Go Back")
.addLore("Click to go back to the", "Quick Compass!")
.build(), (player, clickType) -> getPlugin().getQuickShop().attemptShopOpen(player));
}
protected IButton getButtonFor(String serverGroupPrefix, String name)
{
return (player, clickType) -> getShop().openPageForPlayer(player, getShop().getDirectServerPage(player, name, getPlugin().getServerGroupByPrefix(serverGroupPrefix)));
}
}

View File

@ -1,4 +1,4 @@
package mineplex.hub.server.newui;
package mineplex.hub.server.ui.server;
import java.util.ArrayList;
import java.util.Comparator;
@ -7,7 +7,6 @@ import java.util.concurrent.TimeUnit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
@ -22,8 +21,6 @@ import mineplex.core.game.status.GameInfo.GameDisplayStatus;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.hub.server.GameServer;
import mineplex.hub.server.ServerManager;
import mineplex.hub.server.ServerManager.Perm;
@ -81,9 +78,9 @@ public class ServerSelectionPage extends ShopPageBase<ServerManager, ServerSelec
private boolean _showInProgress;
ServerSelectionPage(ServerManager plugin, ServerSelectionShop shop, CoreClientManager clientManager, DonationManager donationManager, ServerGroup serverGroup, Player player)
ServerSelectionPage(ServerManager plugin, ServerSelectionShop shop, CoreClientManager clientManager, DonationManager donationManager, String name, ServerGroup serverGroup, Player player)
{
super(plugin, shop, clientManager, donationManager, serverGroup.getServerNpcName(), player);
super(plugin, shop, clientManager, donationManager, name, player);
_serverGroup = serverGroup;
_openedAt = System.currentTimeMillis();
@ -106,6 +103,11 @@ public class ServerSelectionPage extends ShopPageBase<ServerManager, ServerSelec
{
buildJoinablePage(servers);
}
if (UtilTime.elapsed(_openedAt, MAX_VIEWING_TIME))
{
getPlugin().runSyncLater(() -> getPlayer().closeInventory(), 0);
}
}
private void buildJoinablePage(List<GameServer> servers)
@ -128,7 +130,10 @@ public class ServerSelectionPage extends ShopPageBase<ServerManager, ServerSelec
.setLore(UtilText.splitLineToArray(C.cGray + "Join the best server in an instant. No fiddling to find what server to join, let us pick one for you and join a game as fast as you can.", LineFormat.LORE)),
(player, clickType) ->
{
// TODO select best server
if (!getPlugin().selectBest(player, _serverGroup))
{
playDenySound(player);
}
});
// Public Servers
@ -318,25 +323,30 @@ public class ServerSelectionPage extends ShopPageBase<ServerManager, ServerSelec
);
String footer;
boolean canJoin;
switch (info.getJoinable())
{
case OPEN:
footer = "Click to Join!";
canJoin = true;
break;
case RANKS_ONLY:
if (_ownsUltra)
{
footer = "You have ULTRA! Click to Join!";
canJoin = true;
}
else
{
footer = "ULTRA+ can join. Visit mineplex.com/shop";
canJoin = false;
}
break;
default:
builder.setType(Material.REDSTONE_BLOCK);
footer = "Game is full!";
canJoin = false;
break;
}
@ -353,7 +363,14 @@ public class ServerSelectionPage extends ShopPageBase<ServerManager, ServerSelec
addButton(slot, builder.build(), (player, clickType) ->
{
// TODO select server
if (canJoin && getPlugin().selectServer(player, server))
{
playAcceptSound(player);
}
else
{
playDenySound(player);
}
});
}
@ -368,17 +385,6 @@ public class ServerSelectionPage extends ShopPageBase<ServerManager, ServerSelec
}
}
@EventHandler
public void closeIfIdle(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOW || !UtilTime.elapsed(_openedAt, MAX_VIEWING_TIME))
{
return;
}
getPlayer().closeInventory();
}
private String timeString(int time)
{
time = Math.max(0, time);

View File

@ -0,0 +1,72 @@
package mineplex.hub.server.ui.server;
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.hub.server.ServerManager;
import mineplex.serverdata.data.ServerGroup;
public class ServerSelectionShop extends ShopBase<ServerManager>
{
public ServerSelectionShop(ServerManager plugin, CoreClientManager clientManager, DonationManager donationManager, String name)
{
super(plugin, clientManager, donationManager, name);
}
@Override
protected ShopPageBase<ServerManager, ? extends ShopBase<ServerManager>> buildPagesFor(Player player)
{
return null;
}
public void openServerPage(Player player, ServerGroup serverGroup)
{
ShopPageBase<ServerManager, ? extends ShopBase<ServerManager>> page;
switch (serverGroup.getPrefix())
{
case "SKY":
case "HG":
case "SSM":
page = new ServerTeamsSelectionPage(getPlugin(), this, getClientManager(), getDonationManager(), serverGroup, player);
break;
case "DOM":
page = new ChampionsServerSelectionPage(getPlugin(), this, getClientManager(), getDonationManager(), serverGroup, player);
break;
case "CW4":
page = new CakeWarsServerSelectionPage(getPlugin(), this, getClientManager(), getDonationManager(), serverGroup, player);
break;
default:
page = getDirectServerPage(player, serverGroup.getServerNpcName(), serverGroup);
break;
}
openPageForPlayer(player, page);
}
public ServerSelectionPage getDirectServerPage(Player player, String name, ServerGroup group)
{
return new ServerSelectionPage(getPlugin(), this, getClientManager(), getDonationManager(), name, group, player);
}
public void updatePages()
{
getPageMap().values().forEach(ShopPageBase::refresh);
}
@Override
protected void openShopForPlayer(Player player)
{
getPlugin().getHubManager().GetVisibility().addHiddenPlayer(player);
}
@Override
protected void closeShopForPlayer(Player player)
{
getPlugin().getHubManager().GetVisibility().removeHiddenPlayer(player);
}
}

View File

@ -0,0 +1,50 @@
package mineplex.hub.server.ui.server;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.hub.server.ServerManager;
import mineplex.serverdata.data.ServerGroup;
public class ServerTeamsSelectionPage extends ServerModeSelectionPage
{
public ServerTeamsSelectionPage(ServerManager plugin, ServerSelectionShop shop, CoreClientManager clientManager, DonationManager donationManager, ServerGroup serverGroup, Player player)
{
super(plugin, shop, clientManager, donationManager, serverGroup, player);
}
@Override
protected void buildPage()
{
super.buildPage();
String friendlyName = _serverGroup.getServerNpcName();
addButton(11, new ItemBuilder(Material.SKULL_ITEM, (byte) 3)
.setTitle(C.cYellowB + "Solo " + C.cGoldB + friendlyName)
.addLore(
"",
"Free-for-all!",
C.cRedB + "WARNING: " + C.Reset + "Teaming in Solo Mode is bannable!",
"",
CLICK_TO_PLAY
)
.setPlayerHead(getPlayer().getName())
.build(), getButtonFor(_serverGroup.getPrefix(), "Solo " + friendlyName));
addButton(15, new ItemBuilder(Material.SKULL_ITEM, 2, (byte) 3)
.setTitle(C.cYellowB + "Team " + C.cGoldB + friendlyName)
.addLore(
"",
"2 Player Teams!",
"",
CLICK_TO_PLAY
)
.setPlayerHead(getPlayer().getName())
.build(), getButtonFor(_serverGroup.getTeamServerKey(), "Team " + friendlyName));
}
}

View File

@ -156,9 +156,8 @@ public abstract class Vote<T extends Voteable>
public boolean decrementTimer()
{
int voted = _voteData.size();
int validPlayers = _manager.getValidPlayersForGameStart().size();
return validPlayers != 0 && (voted >= _manager.GetPlayerFull() && voted == validPlayers || --_timer == 0);
return voted >= _manager.GetPlayerFull() && voted == _manager.getValidPlayersForGameStart().size() || --_timer == 0;
}
public int getTimer()