diff --git a/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java new file mode 100644 index 000000000..2976e2b00 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/PlayerInputActionMenu.java @@ -0,0 +1,166 @@ +package mineplex.core.anvilMenu; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import net.minecraft.server.v1_8_R3.*; +import org.apache.commons.lang.StringUtils; +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.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; + +import static sun.audio.AudioPlayer.player; + +/** + * A utility class for creating simple and easy Anvil GUI's that require actions based on a users input. + */ +public abstract class PlayerInputActionMenu implements Listener +{ + + protected MiniPlugin _plugin; + protected Player _player; + protected Inventory _currentInventory; + protected String _itemName = ""; + protected boolean _searching; + protected Party _party; + + public PlayerInputActionMenu(MiniPlugin plugin, Player player, Party party) + { + _player = player; + _plugin = plugin; + _party = party; + player.closeInventory(); + _plugin.registerEvents(this); + } + + public abstract void inputReceived(String name); + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) + { + if (event.getPlayer() == _player) + { + unregisterListener(); + } + } + + public void unregisterListener() + { + if(_currentInventory != null) + { + _currentInventory.clear(); + } + HandlerList.unregisterAll(this); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) + { + if (event.getPlayer() == _player) + { + unregisterListener(); + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) + { + if (event.getRawSlot() < 3) + { + event.setCancelled(true); + + if (event.getRawSlot() == 2) + { + if (_itemName.length() > 1 && !_searching) + { + _searching = true; + inputReceived(_itemName); + } else + { + _player.playSound(_player.getLocation(), Sound.ITEM_BREAK, 1, .6f); + } + } + } else if (event.isShiftClick()) + { + event.setCancelled(true); + } + } + + public void openInventory() + { + + EntityPlayer p = ((CraftPlayer) _player).getHandle(); + + AnvilContainer container = new AnvilContainer(p); + int c = p.nextContainerCounter(); + + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(c, "minecraft:anvil", new ChatMessage(Blocks.ANVIL.a() + ".name", new Object[0])); + + UtilPlayer.sendPacket(_player, packet); + + // Set their active container to the container + p.activeContainer = container; + + // Set their active container window id to that counter stuff + p.activeContainer.windowId = c; + + // Add the slot listener + p.activeContainer.addSlotListener(p); // Set the items to the items from the inventory given + _currentInventory = container.getBukkitView().getTopInventory(); + + _currentInventory.setItem(0, new ItemBuilder(Material.PAPER).setRawTitle("Input Text...").build()); + _currentInventory.setItem(2, new ItemBuilder(Material.PAPER).setRawTitle("Search").build()); + } + + private class AnvilContainer extends ContainerAnvil + { + private String n; + + public AnvilContainer(EntityHuman entity) + { + super(entity.inventory, entity.world, new BlockPosition(0, 0, 0), entity); + } + + @Override + public boolean a(EntityHuman entityhuman) + { + return true; + } + + @Override + public void a(String origString) + { + n = origString; + _itemName = origString; + + if (getSlot(2).hasItem()) + { + net.minecraft.server.v1_8_R3.ItemStack itemstack = getSlot(2).getItem(); + + if (StringUtils.isBlank(origString)) + { + itemstack.r(); + } else + { + itemstack.c(this.n); + } + } + + e(); + } + + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java new file mode 100644 index 000000000..ab4999c54 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/anvilMenu/player/PlayerNameMenu.java @@ -0,0 +1,58 @@ +package mineplex.core.anvilMenu.player; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.anvilMenu.PlayerInputActionMenu; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +import static net.minecraft.server.v1_8_R3.PotionBrewer.n; + +/** + * A wrapped menu that handles looking for players specifically. + */ +public abstract class PlayerNameMenu extends PlayerInputActionMenu +{ + + protected CoreClientManager _clientManager; + + public PlayerNameMenu(MiniPlugin plugin, CoreClientManager clientManager, Player player, Party party) + { + super(plugin, player, party); + _clientManager = clientManager; + } + + public abstract void onSuccess(String name); + + public abstract void onFail(String name); + + @Override + public void inputReceived(String name) + { + if(Bukkit.getPlayer(name) != null) + { + onSuccess(Bukkit.getPlayer(name).getName()); + return; + } + _clientManager.checkPlayerName(_player, _itemName, result -> { + _searching = false; + + if (result != null) + { + onSuccess(result); + } else + { + onFail(name); + _currentInventory.setItem(2, new ItemBuilder(Material.PAPER) + .setTitle(C.cYellow + "0" + C.cGray + " matches for [" + C.cYellow + name + C.cGray + "]") + .build()); + _player.playSound(_player.getLocation(), Sound.ITEM_BREAK, 1, .6f); + } + }); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/InviteData.java b/Plugins/Mineplex.Core/src/mineplex/core/party/InviteData.java new file mode 100644 index 000000000..b401da6d1 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/InviteData.java @@ -0,0 +1,27 @@ +package mineplex.core.party; + +/** + * Serializable invite data + */ +public class InviteData +{ + + private String _invitedTo; + private String _serverFrom; + + public InviteData(String invitedTo, String serverFrom) + { + _invitedTo = invitedTo; + _serverFrom = serverFrom; + } + + public String getInvitedTo() + { + return _invitedTo; + } + + public String getServerFrom() + { + return _serverFrom; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/Lang.java b/Plugins/Mineplex.Core/src/mineplex/core/party/Lang.java new file mode 100644 index 000000000..1132b0ee2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/Lang.java @@ -0,0 +1,99 @@ +package mineplex.core.party; + +import mineplex.core.common.util.C; +import org.bukkit.entity.Player; + +import java.text.MessageFormat; + +/** + * All chat messages for the party system to align with PE + */ +public enum Lang +{ + + //Party + SUCCESS_SERVER_CONNECT("Sending you and your party to {0}..."), + INVITE_SUCCESS_PLAYER("Successfully invited {0} to the party."), + SUCCESS_INVITE("{0} has invited {1} to the party."), + INVITE_RECEIVED("You have been invited to {0}'s party! You have 60 seconds to reply."), + INVITE_ACCEPT("{0} has joined the party."), + INVITE_DENY("{0} declined your invite."), + INVITE_EXPIRED("{0} did not respond in time."), + INVITE_EXPIRED_PLAYER("Your invite to {0}'s party has expired."), + + SHOW_MEMBERS("Party members: {0}."), + REMOVE_PLAYER("{0} has left the party."), + REMOVE_PLAYER_KICK("{0} has been removed from the party."), + ADD_MEMBER("{0} has joined the party."), + LEFT("You have left your party."), + PARTY_OWNER_LEAVE("{0} has left the party. {1} is the new party owner."), + TRANSFER_OWNER("{0} has given party leadership to {1}."), + DISBANDED("Your party has been disbanded, due to a lack of players."), + DISBANDED_BY_OWNER("Your party has been disbanded!"), + REMOVED("You have been removed from the party."), + + NOT_EXIST("Error: {0} is not in a party right now."), + ALREADY_MEMBER("Error: {0} is already in the party!"), + NO_PARTY("Error: You are not in a party!"), + ALREADY_IN("Error: You are already in a party!"), + NOT_MEMBER("Error: {0} is not a member of your party."), + NOT_INVITED("Error: You do not have a pending invite to {0}'s party."), + NOT_OWNER("Error: You must be the party owner to do this!"), + NOT_OWNER_SERVER("Error: You must be the owner to move servers!"), + ALREADY_INVITED("Error: {0} has already been invited."), + PARTY_FULL("Error: Your party is full!"), + SERVER_CLOSED("Error: Your server is closed and you cannot invite players to join it right now!"), + SERVER_FULL("Error: Your server is full and you cannot invite more players to join it right now!"), + PLAYER_IN_DIFFERENT_PARTY("Error: {0} is in a different party.") + + ; + + private String _message; + + Lang(String message) + { + _message = message; + } + + public void send(Player player, String... args) + { + player.sendMessage(C.mHead + "Party> " + getFormatted(args)); + } + + public void send(Party party, String... args) + { + party.sendMessage(C.mHead + "Party> " + getFormatted(args)); + } + + private String getFormatted(String[] args) + { + String color = C.mBody; + + if(args.length == 0) + { + return _message; + } + + if(_message.startsWith("Error:")) + { + color = C.cRed; + } + + int firstIndex = _message.indexOf("{"); + + String[] coloredArgs = new String[args.length]; + + for(int i = 0; i < args.length; i++) + { + coloredArgs[i] = C.cYellow + args[i] + color; + } + + String message = MessageFormat.format(_message, coloredArgs); + + String coloredRest = message.substring(firstIndex); + + message = color + message.substring(0, firstIndex) + coloredRest; + return message; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/Party.java b/Plugins/Mineplex.Core/src/mineplex/core/party/Party.java index baa697e0a..d649d6c5f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/Party.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/Party.java @@ -1,439 +1,278 @@ package mineplex.core.party; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; - -import mineplex.core.common.Rank; -import mineplex.core.common.jsonchat.ChildJsonMessage; -import mineplex.core.common.jsonchat.ClickEvent; -import mineplex.core.common.jsonchat.JsonMessage; -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.UtilTime; -import mineplex.core.party.redis.RedisPartyData; -import mineplex.serverdata.Region; -import mineplex.serverdata.commands.ServerTransfer; -import mineplex.serverdata.commands.TransferCommand; -import mineplex.serverdata.data.ServerGroup; -import mineplex.serverdata.servers.ServerManager; - +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import mineplex.core.common.util.UtilServer; +import mineplex.core.party.constants.PartyRemoveReason; +import mineplex.core.party.event.PartyTransferOwnerEvent; +import mineplex.core.party.event.PartyTransferOwnerEvent.TransferReason; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Sound; import org.bukkit.entity.Player; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Scoreboard; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * The main object for Parites. + */ public class Party { - private PartyManager _manager; - private boolean _isHub; - private String _creator; - private String _previousServer; + /** + * This is controls whether or not the owner is currently in the menu, and kicking members + */ + private transient boolean _ownerKickMode = false; - private ArrayList _players = new ArrayList(); - private NautHashMap _invitee = new NautHashMap(); + /** + * Asserts if this party has already been put into teams in order to prevent the Arcade from reassigning teams + */ + private transient boolean _alreadyTeamed = false; - private Scoreboard _scoreboard; - private Objective _scoreboardObj; - private ArrayList _scoreboardLast = new ArrayList(); + /** + * The standard size for parties, for ALL {@code {@link mineplex.core.common.Rank}} + */ + private static final int PARTY_MIN_SIZE = 5; - private long _partyOfflineTimer = -1; - private long _informNewLeaderTimer = -1; + /** + * An upgraded size for the party, given to donators and staff. + */ + private static final int PARTY_MAX_SIZE = 10; - public Party(PartyManager manager, RedisPartyData partyData) + /** + * The current leader of this party + */ + private String _owner; + + /** + * The names of all current party members + */ + private List _members; + + /** + * The UUIDS of all current party members + */ + private List _membersByUUID; + + /** + * All current pending invites + */ + private Map _invites; + + /** + * This party's max size + */ + private int _size; + + /** + * Empty constructor for GSON + */ + public Party() { - this(manager); - _players = new ArrayList(Arrays.asList(partyData.getPlayers())); - _creator = partyData.getLeader(); - _previousServer = partyData.getPreviousServer(); } - public Party(PartyManager manager) + /** + * Creates a new fresh party instance + * + * @param owner The owner / leader of the party. + */ + public Party(String owner) { - _manager = manager; - Region region = manager.getPlugin().getConfig().getBoolean("serverstatus.us") ? Region.US : Region.EU; - String groupName = manager.getPlugin().getConfig().getString("serverstatus.group"); + _owner = owner; + _members = Lists.newArrayList(); + _invites = Maps.newHashMap(); + _members.add(owner); + _membersByUUID = Lists.newArrayList(); + } - ServerGroup serverGroup = ServerManager.getServerRepository(region).getServerGroup(groupName); + public String getOwner() + { + return _owner; + } - if (serverGroup == null) + /** + * Get the current members by their IGN + * + * @return The list of named party members + */ + public List getMembers() + { + return _members; + } + + public Map getInvites() + { + return _invites; + } + + /** + * An alternate method to get the owner of the party. + * While this does not have any difference to using {@code getOwner}, it may serve a purpose in the future, should we wish to allow + * donators to name their party something custom. + * + * @return This party's name + */ + public String getName() + { + return _owner; + } + + /** + * Send's a message to the party + * + * @param message The string message to send to all players in the party + */ + public void sendMessage(String message) + { + getMembers().stream().map(Bukkit::getPlayer).forEach(player -> player.sendMessage(message)); + } + + public int getSize() + { + return _size; + } + + /** + * Set's this party's size cap base off the current players rank + * + * @param increased true if this party should have the increased size + */ + public void setSize(boolean increased) + { + _size = increased ? PARTY_MAX_SIZE : PARTY_MIN_SIZE; + } + + /** + * Called when a player is added to the party. + * + * @param player The name of the player + */ + public void onPlayerAdd(String player) + { + _invites.remove(player); + if(_members.contains(player)) + { return; - - _isHub = !serverGroup.getArcadeGroup(); - - if (_isHub) + } + _members.add(player); + Lang.ADD_MEMBER.send(this, player); + getMembers().forEach(s -> { - // Scoreboard - _scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); - _scoreboardObj = _scoreboard.registerNewObjective("Party", "dummy"); - _scoreboardObj.setDisplaySlot(DisplaySlot.SIDEBAR); + Player player1 = Bukkit.getPlayer(s); + player1.playSound(player1.getLocation(), Sound.NOTE_PLING, 1.0F, 10.0F); + }); + } - _scoreboard.registerNewTeam(ChatColor.GREEN + "Members"); - - // Scoreboard Ranks - for (Rank rank : Rank.values()) + /** + * Called when a member of the party is removed + * + * @param player The name of the player + * @param reason The reason for his removal. + */ + public void onPlayerRemove(String player, PartyRemoveReason reason) + { + if(reason == PartyRemoveReason.DISBANDED) + { + Player bukkitPlayer = Bukkit.getPlayerExact(player); + Lang.DISBANDED.send(bukkitPlayer); + bukkitPlayer.closeInventory(); + return; + } + if(_members.size() <= 0) + { + return; + } + if(reason == PartyRemoveReason.LEFT) + { + if(player.equalsIgnoreCase(_owner) && _members.size() > 1) { - if (rank != Rank.ALL) - _scoreboard.registerNewTeam(rank.Name).setPrefix(rank.getTag(true, true) + ChatColor.RESET + " "); - else - _scoreboard.registerNewTeam(rank.Name).setPrefix(""); + _owner = _members.get(0); + Lang.TRANSFER_OWNER.send(this, player, _owner); + PartyTransferOwnerEvent event = new PartyTransferOwnerEvent(this, _owner, player, TransferReason.LEFT); + UtilServer.getServer().getPluginManager().callEvent(event); + return; } + Lang.REMOVE_PLAYER.send(this, player); + return; + } + if(reason == PartyRemoveReason.OTHER) + { + return; + } + if(reason == PartyRemoveReason.KICKED) + { + Lang.REMOVE_PLAYER_KICK.send(this, player); + } + } - _scoreboard.registerNewTeam("Party").setPrefix(ChatColor.LIGHT_PURPLE + C.Bold + "Party" + ChatColor.RESET + " "); + /** + * Gets the current state of whether or not the owner is kicking people in the UI. + * + * @return true if the owner is kicking people + */ + public boolean isOwnerKickMode() + { + return _ownerKickMode; + } - // Add Players - for (Player player : Bukkit.getOnlinePlayers()) + /** + * Set's the current state of kicking players + * + * @param ownerKickMode true if the owner is kicking people + */ + public void setOwnerKickMode(boolean ownerKickMode) + { + _ownerKickMode = ownerKickMode; + } + + /** + * Set's the new owner for this party instance + * + * @param owner The new owner's name + */ + public void setOwner(String owner) + { + _owner = owner; + } + + /** + * Get a list of all members in the party by their UUID + * + * @return A list of members by UUID + */ + public List getMembersByUUID() + { + return _membersByUUID; + } + + public boolean alreadyTeamed() + { + return _alreadyTeamed; + } + + public void setAlreadyTeamed(boolean alreadyTeamed) + { + _alreadyTeamed = alreadyTeamed; + } + + /** + * Check to see if this party contains a certain player name + * This is case-insensitive + * + * @param name The players name + * @return true If the player is in the party + */ + public boolean contains(String name) + { + for(String s : _members) + { + if(s.equalsIgnoreCase(name)) { - _scoreboard.getTeam(_manager.GetClients().Get(player).GetRank().Name).addPlayer(player); + return true; } } - } - - public void JoinParty(Player player) - { - // Add Leader - if (_players.isEmpty()) - { - _players.add(player.getName()); - - UtilPlayer.message(player, F.main("Party", "You created a new Party.")); - - _creator = player.getName(); - } - else - { - _players.add(player.getName()); - _invitee.remove(player.getName()); - - Announce(F.elem(player.getName()) + " has joined the party!"); - } - - if (_isHub) - { - _scoreboard.getTeam("Party").addPlayer(player); - } - } - - public void InviteParty(Player player, boolean inviteeInParty) - { - _invitee.put(player.getName(), System.currentTimeMillis()); - - // Decline - if (_players.contains(player.getName())) - { - UtilPlayer.message(player, F.main("Party", F.name(player.getName()) + " is already in the Party.")); - player.playSound(player.getLocation(), Sound.NOTE_BASS, 1f, 1.5f); - } - - // Announce - Announce(F.name(player.getName()) + " has been invited to your Party."); - - // Inform - UtilPlayer.message(player, F.main("Party", F.name(GetLeader()) + " invited you to their Party.")); - - // Instruct - if (inviteeInParty) - { - ChildJsonMessage message = new JsonMessage("").extra(C.mHead + "Party> " + C.mBody + "Type "); - - message.add(F.link("/party leave")).click(ClickEvent.RUN_COMMAND, "/party leave"); - - message.add(C.mBody + " then "); - - message.add(F.link("/party " + GetLeader())).click(ClickEvent.RUN_COMMAND, "/party " + GetLeader()); - - message.add(C.mBody + " to join."); - - message.sendToPlayer(player); - } - else - { - ChildJsonMessage message = new JsonMessage("").extra(C.mHead + "Party> " + C.mBody + "Type "); - - message.add(F.link("/party " + GetLeader())).click(ClickEvent.RUN_COMMAND, "/party " + GetLeader()); - - message.add(C.mBody + " to join."); - - message.sendToPlayer(player); - } - - player.playSound(player.getLocation(), Sound.NOTE_PLING, 1f, 1.5f); - } - - public void LeaveParty(Player player) - { - // Announce - Announce(F.name(player.getName()) + " has left the Party."); - - boolean leader = player.equals(GetLeader()); - - _players.remove(player.getName()); - - if (_isHub) - { - // Set Scoreboard - _scoreboard.getTeam(_manager.GetClients().Get(player).GetRank().Name).addPlayer(player); - } - - if (leader && _players.size() > 0) - { - Announce("Party Leadership passed on to " + F.name(GetLeader()) + "."); - } - } - - public void KickParty(String player) - { - // Announce - Announce(F.name(player) + " was kicked from the Party."); - - _players.remove(player); - } - - public void PlayerJoin(Player player) - { - if (_isHub) - { - // Scoreboard - if (_players.contains(player.getName())) - _scoreboard.getTeam("Party").addPlayer(player); - else if (_manager.GetClients().Get(player) != null) - _scoreboard.getTeam(_manager.GetClients().Get(player).GetRank().Name).addPlayer(player); - } - - if (_creator.equals(player.getName())) - { - _players.remove(player.getName()); - _players.add(0, player.getName()); - - if (_informNewLeaderTimer < System.currentTimeMillis()) - { - Announce("Party Leadership returned to " + F.name(GetLeader()) + "."); - } - - if (_previousServer != null) - { - for (String playerName : _players) - { - Player p = Bukkit.getPlayerExact(playerName); - - if (p != null) - { - continue; - } - - TransferCommand transferCommand = new TransferCommand( - new ServerTransfer(playerName, _manager.getServerName())); - - transferCommand.setTargetServers(_previousServer); - - transferCommand.publish(); - } - - _previousServer = null; - } - } - } - - // Shuffle Leader - public void PlayerQuit(Player player) - { - if (player.getName().equals(GetLeader())) - { - _players.remove(player.getName()); - _players.add(player.getName()); - - if (_informNewLeaderTimer < System.currentTimeMillis()) - { - Announce("Party Leadership passed on to " + F.name(GetLeader()) + "."); - } - } - } - - public void Announce(String message) - { - for (String name : _players) - { - Player player = UtilPlayer.searchExact(name); - - if (player != null && player.isOnline()) - { - UtilPlayer.message(player, F.main("Party", message)); - player.playSound(player.getLocation(), Sound.NOTE_PLING, 1f, 1.5f); - } - } - } - - public void ExpireInvitees() - { - Iterator inviteeIterator = _invitee.keySet().iterator(); - - while (inviteeIterator.hasNext()) - { - String name = inviteeIterator.next(); - - if (UtilTime.elapsed(_invitee.get(name), 60000)) - { - Announce(F.name(name) + " did not respond to the Party invite."); - inviteeIterator.remove(); - } - } - } - - public String GetLeader() - { - if (_players.isEmpty()) - return _creator; - - return _players.get(0); - } - - public Collection GetPlayers() - { - return _players; - } - - public Collection GetPlayersOnline() - { - ArrayList players = new ArrayList(); - - for (String name : _players) - { - Player player = UtilPlayer.searchExact(name); - if (player != null) - players.add(player); - } - - return players; - } - - public Collection GetInvitees() - { - return _invitee.keySet(); - } - - public void UpdateScoreboard() - { - if (_isHub) - { - _scoreboardObj.setDisplayName(GetLeader() + "'s Party"); - - // Clear Past - for (String pastLine : _scoreboardLast) - _scoreboard.resetScores(pastLine); - _scoreboardLast.clear(); - - int i = 16; - - // Add New - for (int j = 0; j < _players.size(); j++) - { - String name = _players.get(j); - Player player = UtilPlayer.searchExact(name); - - ChatColor col = ChatColor.GREEN; - if (player == null) - col = ChatColor.RED; - - String line = col + name; - - if (line.length() > 16) - line = line.substring(0, 16); - - _scoreboardObj.getScore(line).setScore(i); - - _scoreboardLast.add(line); - - i--; - } - - // Add New - for (String name : _invitee.keySet()) - { - int time = 1 + (int) ((60000 - (System.currentTimeMillis() - _invitee.get(name))) / 1000); - - String line = time + " " + ChatColor.GRAY + name; - - if (line.length() > 16) - line = line.substring(0, 16); - - _scoreboardObj.getScore(line).setScore(i); - - _scoreboardLast.add(line); - - i--; - } - - // Set Scoreboard - for (String name : _players) - { - Player player = UtilPlayer.searchExact(name); - - if (player != null) - { - if (!player.getScoreboard().equals(_scoreboard)) - { - player.setScoreboard(_scoreboard); - } - } - } - } - } - - public boolean IsDead() - { - if (_players.size() == 0) - return true; - - if (_players.size() == 1 && _invitee.size() == 0) - return true; - - int online = 0; - for (String name : _players) - { - Player player = UtilPlayer.searchExact(name); - if (player != null) - online++; - } - - // One or Less Members Online - Expirey Countdown - if (online <= 1) - { - if (_partyOfflineTimer == -1) - { - _partyOfflineTimer = System.currentTimeMillis(); - } - else - { - if (UtilTime.elapsed(_partyOfflineTimer, online == 0 ? 5000 : 120000)) // 5 seconds for no players, 2 minutes if - // one player. - { - return true; - } - } - } - else if (_partyOfflineTimer > 0) - { - _partyOfflineTimer = -1; - } - return false; } - - public void resetWaitingTime() - { - _partyOfflineTimer = -1; - } - - public void switchedServer() - { - _informNewLeaderTimer = System.currentTimeMillis() + 5000; - } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/PartyEventListener.java b/Plugins/Mineplex.Core/src/mineplex/core/party/PartyEventListener.java new file mode 100644 index 000000000..f7e334a84 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/PartyEventListener.java @@ -0,0 +1,153 @@ +package mineplex.core.party; + +import mineplex.core.common.Rank; +import mineplex.core.party.constants.PartyRemoveReason; +import mineplex.core.party.event.PartyMemberKickGUIEvent; +import mineplex.core.party.event.PartyTransferOwnerEvent; +import mineplex.core.party.ui.Menu; +import mineplex.core.portal.ServerTransferEvent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +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.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +/** + * Event handler for Parties + */ +public class PartyEventListener implements Listener +{ + + private final PartyManager _plugin; + + public PartyEventListener(PartyManager plugin) + { + _plugin = plugin; + _plugin.getPluginManager().registerEvents(this, plugin.getPlugin()); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + + player.getInventory().setItem(PartyManager.INTERFACE_SLOT, PartyManager.INTERFACE_ITEM); + + String partyName = _plugin.getInviteManager().getPartyWaiting(player.getUniqueId()); + + if (partyName == null) + { + return; + } + + Party party = _plugin.getParty(partyName); + + Player bukkitPlayer = Bukkit.getPlayerExact(partyName); + + if (party == null) + { + party = new Party(partyName); + + if (bukkitPlayer != null && _plugin.getClientManager().Get(bukkitPlayer).GetRank().has(Rank.ULTRA)) + { + party.setSize(true); + } else + { + party.setSize(false); + } + + _plugin.addParty(party); + } + + _plugin.getInviteManager().cancelTask(player.getUniqueId()); + + _plugin.getMethodManager().addToParty(Bukkit.getPlayerExact(partyName), party); + + _plugin.getMethodManager().addToParty(player, party); + + _plugin.getInviteManager().removeFromWaiting(player.getUniqueId()); + + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + Party party = _plugin.getParty(player); + + _plugin.getInviteManager().removeAll(player.getUniqueId()); + + if (party == null) + { + return; + } + + PartyRemoveReason reason = PartyRemoveReason.LEFT; + + if(_plugin.getJoinManager().isTransferring(player)) + { + reason = PartyRemoveReason.OTHER; + } + + _plugin.getMethodManager().removeFromParty(player, reason); + } + + + @EventHandler + public void onTransferOwner(PartyTransferOwnerEvent event) + { + _plugin.getMethodManager().transferOwner(event.getNewOwner(), event.getOldOwner()); + } + + @EventHandler + public void onKick(PartyMemberKickGUIEvent event) + { + Player clicked = Bukkit.getPlayerExact(event.getPlayerClicked()); + Lang.REMOVED.send(clicked); + _plugin.getMethodManager().removeFromParty(clicked, PartyRemoveReason.KICKED); + Menu.get(event.getOwner().getUniqueId()).resetAndUpdate(event.getOwner()); + } + + @EventHandler + public void onTransfer(ServerTransferEvent event) + { + Player player = event.getPlayer(); + Party party = _plugin.getParty(player); + + if (party == null) + { + return; + } + + if(event.isDraggedByParty()) + { + return; + } + + event.setCancel(true); + + if (!party.getOwner().equalsIgnoreCase(player.getName())) + { + Lang.NOT_OWNER_SERVER.send(player); + return; + } + + _plugin.getJoinManager().requestServerJoin(event.getServer(), party); + + } + + @EventHandler + public void onClick(PlayerInteractEvent event) + { + if(event.hasItem() && event.getItem().getType() == Material.NAME_TAG) + { + event.setCancelled(true); + event.getPlayer().chat("/party"); + } + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java index b79283d76..918d3f8b6 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java @@ -1,73 +1,129 @@ package mineplex.core.party; -import java.util.HashSet; -import java.util.Iterator; - +import com.google.common.collect.Maps; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; -import mineplex.core.common.util.NautHashMap; -import mineplex.core.party.commands.PartyCommand; -import mineplex.core.party.redis.RedisPartyData; -import mineplex.core.party.redis.RedisPartyHandler; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.command.PartyCommand; +import mineplex.core.party.manager.PartyInviteManager; +import mineplex.core.party.manager.PartyJoinManager; +import mineplex.core.party.manager.PartyMethodManager; +import mineplex.core.party.manager.PartyRedisManager; +import mineplex.core.party.ui.MenuListener; import mineplex.core.portal.Portal; -import mineplex.core.portal.ServerTransferEvent; import mineplex.core.preferences.PreferencesManager; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.serverdata.commands.ServerCommandManager; - +import mineplex.serverdata.Utility; +import mineplex.serverdata.servers.ServerManager; +import org.bukkit.Material; 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.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; +import java.util.Map; +import java.util.UUID; + public class PartyManager extends MiniPlugin { - private CoreClientManager _clientManager; - private PreferencesManager _preferenceManager; - private Portal _portal; - private String _serverName; - public NautHashMap _partyLeaderMap = new NautHashMap(); + /** + * The item given to a player in his hotbar to manage the Parties via the new UI. + */ + public static final ItemStack INTERFACE_ITEM = new ItemBuilder(Material.NAME_TAG).setTitle(C.cGreen + "Parties").build(); + /** + * The slow to which it goes in. + */ + public static final int INTERFACE_SLOT = 5; + + //Managers + private final Portal _portal; + private final CoreClientManager _clientManager; + private final PreferencesManager _preferencesManager; + private final PartyRedisManager _redisManager; + private final PartyInviteManager _inviteManager; + private final PartyJoinManager _joinManager; + private final PartyMethodManager _methodManager; + + /** + * This local instance's name + */ + private final String _serverName; + + /** + * A map of player's in parties server wide. + */ + private final Map _players = Maps.newHashMap(); + + /** + * A map of owner (name) -> party server wide + */ + private final Map _parties = Maps.newHashMap(); public PartyManager(JavaPlugin plugin, Portal portal, CoreClientManager clientManager, PreferencesManager preferenceManager) { - super("Party Manager", plugin); - + super("Parties", plugin); _portal = portal; _clientManager = clientManager; - _preferenceManager = preferenceManager; - _serverName = getPlugin().getConfig().getString("serverstatus.name"); + _preferencesManager = preferenceManager; - ServerCommandManager.getInstance().registerCommandType("RedisPartyData", RedisPartyData.class, - new RedisPartyHandler(this)); - } + _serverName = _plugin.getConfig().getString("serverstatus.name"); + + _redisManager = new PartyRedisManager(this, _serverName, + Utility.generatePool(ServerManager.getMasterConnection()), + Utility.generatePool(ServerManager.getSlaveConnection())); + + _inviteManager = new PartyInviteManager(this, _redisManager); + _joinManager = new PartyJoinManager(this); + _methodManager = new PartyMethodManager(this); - @Override - public void addCommands() - { addCommand(new PartyCommand(this)); + getPluginManager().registerEvents(new MenuListener(), getPlugin()); + new PartyEventListener(this); } - public CoreClientManager GetClients() + public Party getParty(String party) + { + return _parties.get(party); + } + + public Party getParty(Player player) + { + return _players.get(player.getUniqueId()); + } + + public void addParty(Party party) + { + _parties.put(party.getName(), party); + } + + public void removeParty(Party party) + { + _parties.remove(party.getName()); + } + + public Portal getPortal() + { + return _portal; + } + + public CoreClientManager getClientManager() { return _clientManager; } - public PreferencesManager getPreferenceManager() + public PreferencesManager getPreferencesManager() { - return _preferenceManager; + return _preferencesManager; } - public Party CreateParty(Player player) + public PartyRedisManager getRedisManager() { - Party party = new Party(this); - party.JoinParty(player); - _partyLeaderMap.put(player.getName(), party); + return _redisManager; + } - return party; + public PartyInviteManager getInviteManager() + { + return _inviteManager; } public String getServerName() @@ -75,107 +131,23 @@ public class PartyManager extends MiniPlugin return _serverName; } - public void addParty(Party party) + public PartyJoinManager getJoinManager() { - if (_partyLeaderMap.containsKey(party.GetLeader())) - _partyLeaderMap.get(party.GetLeader()).resetWaitingTime(); - else - _partyLeaderMap.put(party.GetLeader(), party); + return _joinManager; } - @EventHandler - public void serverTransfer(ServerTransferEvent event) + public PartyMethodManager getMethodManager() { - if (event.isDraggedByParty()) - return; - - Party party = _partyLeaderMap.get(event.getPlayer().getName()); - - if (party != null) - { - party.switchedServer(); - - RedisPartyData data = new RedisPartyData(party, _serverName); - data.setTargetServers(event.getServer()); - data.publish(); - - for (Player player : party.GetPlayersOnline()) - { - if (player != event.getPlayer()) - { - _portal.sendPlayerToServer(player, event.getServer(), true); - } - } - } + return _methodManager; } - @EventHandler(priority = EventPriority.MONITOR) - public void PlayerJoin(PlayerJoinEvent event) + public Map getPlayerParties() { - try - { - for (Party party : _partyLeaderMap.values()) - { - party.PlayerJoin(event.getPlayer()); - } - } - catch (Exception ex) - { - throw ex; - } + return _players; } - @EventHandler - public void PlayerQuit(PlayerQuitEvent event) + public Map getParties() { - for (Party party : _partyLeaderMap.values()) - { - party.PlayerQuit(event.getPlayer()); - } - } - - @EventHandler - public void Update(UpdateEvent event) - { - if (event.getType() != UpdateType.FAST) - return; - - ExpireParties(); - - for (Party party : _partyLeaderMap.values()) - { - party.ExpireInvitees(); - party.UpdateScoreboard(); - } - } - - public void ExpireParties() - { - Iterator partyIterator = _partyLeaderMap.values().iterator(); - - while (partyIterator.hasNext()) - { - Party party = partyIterator.next(); - - // Empty Party - if (party.IsDead()) - { - party.Announce("Your Party has been closed."); - partyIterator.remove(); - } - } - } - - public Party GetParty(Player player) - { - for (Party party : _partyLeaderMap.values()) - { - if (party.GetPlayers().contains(player.getName())) - { - return party; - } - } - - return null; + return _parties; } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java new file mode 100644 index 000000000..8944428bf --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java @@ -0,0 +1,94 @@ +package mineplex.core.party.command; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.menus.PartyInvitesMenu; +import mineplex.core.party.ui.menus.PartyMainMenu; +import mineplex.core.party.ui.menus.PartyOwnerMenu; +import mineplex.core.party.ui.menus.PartyViewMenu; +import org.bukkit.entity.Player; + +/** + * Command handler for party commands + */ +public class PartyCommand extends CommandBase +{ + + private final String[] HELP = { + F.main("Party", "Party Commands (Click the command!)"), + help("", "Brings up the Party GUI"), + help("", "Send an invitation to a player."), + help("leave", "Leave your current party."), + C.cBlue + "Party> " + C.cWhite + "# " + C.cGray + "- Send a message to your party.", + C.cGreenB + "All party functions have been moved to the GUI!", + C.cGreenB + "Click the NameTag in your hotbar to get started!" + }; + + public PartyCommand(PartyManager plugin) + { + super(plugin, Rank.ALL, "party", "z", "partyaccept", "partydeny", "openinvitesmenu", "partyinvite"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length == 0) + { + Party party = Plugin.getParty(caller); + if (party == null) + { + new PartyMainMenu(Plugin).open(caller); + return; + } + if (party.getOwner().equalsIgnoreCase(caller.getName())) + { + new PartyOwnerMenu(party, Plugin).open(caller); + return; + } + new PartyViewMenu(party, Plugin).open(caller); + return; + } + if(_aliasUsed.equalsIgnoreCase("openinvitesmenu")) + { + new PartyInvitesMenu(Plugin).open(caller); + return; + } + if(args.length == 1) + { + String arg = args[0]; + if (_aliasUsed.equalsIgnoreCase("partyaccept")) + { + Plugin.getMethodManager().respondToInvite(caller, arg, true); + return; + } + if (_aliasUsed.equalsIgnoreCase("partydeny")) + { + Plugin.getMethodManager().respondToInvite(caller, arg, false); + return; + } + if(_aliasUsed.equalsIgnoreCase("partyinvite")) + { + Plugin.getMethodManager().invite(caller, arg); + return; + } + if(arg.equalsIgnoreCase("leave")) { + Plugin.getMethodManager().leaveParty(caller); + return; + } + Plugin.getMethodManager().invite(caller, arg); + return; + } + caller.sendMessage(HELP); + } + + private String help(String command, String description) + { + return C.cBlue + "Party> " + C.cWhite + "/party " + command + C.cGray + " - " + description; + } + +} + diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/commands/PartyCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/party/commands/PartyCommand.java deleted file mode 100644 index 1c8fcbfbb..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/commands/PartyCommand.java +++ /dev/null @@ -1,177 +0,0 @@ -package mineplex.core.party.commands; - -import mineplex.core.command.CommandBase; -import mineplex.core.common.Rank; -import mineplex.core.common.jsonchat.ChildJsonMessage; -import mineplex.core.common.jsonchat.ClickEvent; -import mineplex.core.common.jsonchat.JsonMessage; -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.party.Party; -import mineplex.core.party.PartyManager; - -import org.bukkit.Bukkit; -import org.bukkit.Sound; -import org.bukkit.entity.Player; - -public class PartyCommand extends CommandBase -{ - public PartyCommand(PartyManager plugin) - { - super(plugin, Rank.ALL, new String[] - { - "party", "z" - }); - } - - @Override - public void Execute(Player caller, String[] args) - { - if (args == null || args.length == 0 || (args[0].equalsIgnoreCase("kick") && args.length < 2)) - { - UtilPlayer.message(caller, F.main("Party", "Listing Party Commands;")); - UtilPlayer.message(caller, F.value(0, "/party ", "Join/Create/Invite Player")); - UtilPlayer.message(caller, F.value(0, "/party leave", "Leave your current Party")); - UtilPlayer.message(caller, F.value(0, "/party kick ", "Kick player from your Party")); - - return; - } - - // Callers Party - Party party = Plugin.GetParty(caller); - - // Leave - if (args[0].equalsIgnoreCase("leave")) - { - if (party == null) - { - UtilPlayer.message(caller, F.main("Party", "You are not in a Party.")); - } - else - { - party.LeaveParty(caller); - } - - return; - } - - // Leave - if (args[0].equalsIgnoreCase("kick")) - { - if (party == null) - { - UtilPlayer.message(caller, F.main("Party", "You are not in a Party.")); - } - else - { - if (party.GetLeader().equals(caller.getName())) - { - String target = UtilPlayer.searchCollection(caller, args[1], party.GetPlayers(), "Party ", true); - if (target == null) - return; - - if (target.equals(caller.getName())) - { - UtilPlayer.message(caller, F.main("Party", "You cannot kick yourself from the Party.")); - return; - } - - party.KickParty(target); - } - else - { - UtilPlayer.message(caller, F.main("Party", "You are not the Party Leader.")); - } - } - - return; - } - - // Main - Player target = UtilPlayer.searchOnline(caller, args[0], true); - if (target == null) - return; - - if (target.equals(caller)) - { - UtilPlayer.message(caller, F.main("Party", "You cannot Party with yourself.")); - return; - } - - // Preference check - if (!Plugin.getPreferenceManager().Get(target).PartyRequests) - { - UtilPlayer.message( - caller, - F.main("Party", "You may not party with " + F.name(UtilEnt.getName(target)) - + "! They are not accepting party requests!")); - return; - } - - // Invite or Suggest - if (party != null) - { - if (party.GetPlayers().size() + party.GetInvitees().size() >= 16) - { - UtilPlayer.message(caller, "Your party cannot be larger than 16 players."); - caller.playSound(caller.getLocation(), Sound.NOTE_BASS, 1f, 1.5f); - } - // Decline - else if (party.GetPlayers().contains(target.getName())) - { - UtilPlayer.message(caller, F.main("Party", F.name(target.getName()) + " is already in the Party.")); - caller.playSound(caller.getLocation(), Sound.NOTE_BASS, 1f, 1.5f); - } - // Decline - else if (party.GetInvitees().contains(target.getName())) - { - UtilPlayer.message(caller, F.main("Party", F.name(target.getName()) + " is already invited to the Party.")); - caller.playSound(caller.getLocation(), Sound.NOTE_BASS, 1f, 1.5f); - } - // Invite - else if (party.GetLeader().equals(caller.getName())) - { - party.InviteParty(target, Plugin.GetParty(target) != null); - } - // Suggest - else - { - party.Announce(F.name(caller.getName()) + " suggested " + F.name(target.getName()) + " be invited to the Party."); - - Player leader = Bukkit.getPlayerExact(party.GetLeader()); - - if (leader != null) - { - ChildJsonMessage message = new JsonMessage("").extra(C.mHead + "Party> " + C.mBody + "Type "); - - message.add(F.link("/party " + target.getName())).click(ClickEvent.RUN_COMMAND, "/party " + target.getName()); - - message.add(C.mBody + " to invite them."); - - message.sendToPlayer(leader); - } - } - } - // Create or Join - else - { - Party targetParty = Plugin.GetParty(target); - - // Try to Join - if (targetParty != null) - { - if (targetParty.GetInvitees().contains(caller.getName())) - { - targetParty.JoinParty(caller); - return; - } - } - - // Create - party = Plugin.CreateParty(caller); - party.InviteParty(target, Plugin.GetParty(target) != null); - } - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/constants/InviteResponse.java b/Plugins/Mineplex.Core/src/mineplex/core/party/constants/InviteResponse.java new file mode 100644 index 000000000..30212e51d --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/constants/InviteResponse.java @@ -0,0 +1,27 @@ +package mineplex.core.party.constants; + +import mineplex.core.common.util.F; + +/** + * + */ +public enum InviteResponse +{ + + ACCEPTED("{0} has joined the party!"), + DENIED("{0} has declined joining your party."), + EXPIRED("{0} did not respond in time."); + + private String _message; + + InviteResponse(String message) + { + _message = message; + } + + public String format(String target) + { + return _message.replace("{0}", F.name(target)); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/constants/JoinResponseReason.java b/Plugins/Mineplex.Core/src/mineplex/core/party/constants/JoinResponseReason.java new file mode 100644 index 000000000..56cd100e2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/constants/JoinResponseReason.java @@ -0,0 +1,26 @@ +package mineplex.core.party.constants; + +import mineplex.core.common.util.F; + +/** + * + */ +public enum JoinResponseReason +{ + + CANNOT_JOIN_FULL(F.main("Party", "Your party cannot join full servers!")), + SUCCESS(""); + + private String _message; + + JoinResponseReason(String message) + { + _message = message; + } + + public String getMessage() + { + return _message; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/constants/PartyRemoveReason.java b/Plugins/Mineplex.Core/src/mineplex/core/party/constants/PartyRemoveReason.java new file mode 100644 index 000000000..bff47e023 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/constants/PartyRemoveReason.java @@ -0,0 +1,15 @@ +package mineplex.core.party.constants; + +/** + * + */ +public enum PartyRemoveReason +{ + KICKED, + LEFT, + OTHER, + DISBANDED, + DISBANDED_BY_OWNER,; + + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyDataReceivedEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyDataReceivedEvent.java new file mode 100644 index 000000000..d4d25f699 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyDataReceivedEvent.java @@ -0,0 +1,37 @@ +package mineplex.core.party.event; + +import mineplex.core.party.Party; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * An event called when a server receives a PartyPacket containing the information about a party + */ +public class PartyDataReceivedEvent extends Event +{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Party _party; + + public PartyDataReceivedEvent(Party party) + { + _party = party; + } + + public Party getParty() + { + return _party; + } + + @Override + public HandlerList getHandlers() + { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() + { + return HANDLER_LIST; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyMemberKickGUIEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyMemberKickGUIEvent.java new file mode 100644 index 000000000..885567240 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyMemberKickGUIEvent.java @@ -0,0 +1,51 @@ +package mineplex.core.party.event; + +import mineplex.core.party.Party; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * This event is called when an owner clicks a PartyMemberIcon while having Kick mode activated. + */ +public class PartyMemberKickGUIEvent extends Event +{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Party _party; + private final String _playerClicked; + private final Player _owner; + + public PartyMemberKickGUIEvent(Party party, String playerClicked, Player owner) + { + _party = party; + _playerClicked = playerClicked; + _owner = owner; + } + + public String getPlayerClicked() + { + return _playerClicked; + } + + public Player getOwner() + { + return _owner; + } + + public Party getParty() + { + return _party; + } + + @Override + public HandlerList getHandlers() + { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() + { + return HANDLER_LIST; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartySelectServerEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartySelectServerEvent.java new file mode 100644 index 000000000..1509dac3c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartySelectServerEvent.java @@ -0,0 +1,36 @@ +package mineplex.core.party.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * This event is called when a party owner selects the compass icon. + */ +public class PartySelectServerEvent extends Event +{ + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Player _player; + + public PartySelectServerEvent(Player player) + { + _player = player; + } + + public Player getPlayer() + { + return _player; + } + + @Override + public HandlerList getHandlers() + { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() + { + return HANDLER_LIST; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyTransferOwnerEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyTransferOwnerEvent.java new file mode 100644 index 000000000..c21abd883 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/event/PartyTransferOwnerEvent.java @@ -0,0 +1,65 @@ +package mineplex.core.party.event; + +import mineplex.core.party.Party; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * An event called when an owner leaves a party + */ +public class PartyTransferOwnerEvent extends Event +{ + + public enum TransferReason + { + LEFT, + TRANSFER; + } + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Party _party; + private final String _newOwner; + private final String _oldOwner; + private final TransferReason _reason; + + public PartyTransferOwnerEvent(Party party, String newOwner, String oldOwner, TransferReason reason) + { + _party = party; + _newOwner = newOwner; + _oldOwner = oldOwner; + _reason = reason; + } + + public String getNewOwner() + { + return _newOwner; + } + + public String getOldOwner() + { + return _oldOwner; + } + + public TransferReason getReason() + { + return _reason; + } + + public Party getParty() + { + return _party; + } + + @Override + public HandlerList getHandlers() + { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() + { + return HANDLER_LIST; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyInviteManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyInviteManager.java new file mode 100644 index 000000000..580701efc --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyInviteManager.java @@ -0,0 +1,400 @@ +package mineplex.core.party.manager; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.party.InviteData; +import mineplex.core.party.Lang; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.constants.InviteResponse; +import mineplex.core.party.redis.RedisMessageType; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ClickEvent.Action; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * + */ +public class PartyInviteManager +{ + + private final Map> _activeInvites = Maps.newHashMap(); + private final Map _invitedBy = Maps.newHashMap(); + private final Map _awaitingJoin = Maps.newHashMap(); + private final Map _players = Maps.newHashMap(); + private final Map _tasks = Maps.newHashMap(); + + private final PartyManager _plugin; + private final PartyRedisManager _partyRedisManager; + + public PartyInviteManager(PartyManager plugin, PartyRedisManager partyRedisManager) + { + _plugin = plugin; + _partyRedisManager = partyRedisManager; + } + + /** + * Responds to an invite, regardless of the server + * + * @param player The player calling + * @param party The party + * @param accept Whether or not the player accepted the invite + */ + public void respondToInvite(Player player, String party, boolean accept) + { + Player possible = Bukkit.getPlayerExact(party); + + InviteData data = remove(party, player.getUniqueId()); + + _players.remove(player.getUniqueId()); + cancelTask(player.getUniqueId()); + + if(possible != null) + { + Party newParty = _plugin.getParty(party); + if(!accept) + { + String message = C.mHead + "Party> " + C.mBody + InviteResponse.DENIED.format(player.getName()); + if (newParty == null) + { + possible.sendMessage(message); + return; + } + newParty.sendMessage(message); + return; + } + if (newParty == null) + { + newParty = new Party(possible.getName()); + if(_plugin.getClientManager().Get(possible).GetRank().has(Rank.ULTRA)) + { + newParty.setSize(true); + } else + { + newParty.setSize(false); + } + _plugin.addParty(newParty); + _plugin.getMethodManager().addToParty(possible.getUniqueId(), newParty); + } + _plugin.getMethodManager().addToParty(player.getUniqueId(), newParty); + return; + } + + String serverFrom = data.getServerFrom(); + + if(accept) + { + _plugin.getPortal().sendPlayerToServer(player, serverFrom); + } + + _partyRedisManager.publish(serverFrom, RedisMessageType.INVITE_PLAYER_RESPONSE, party, + player.getName(), player.getUniqueId().toString(), accept ? InviteResponse.ACCEPTED.name() : InviteResponse.DENIED.name()); + } + + /** + * Handles a received response via redis + * + * @param sender The player sending the request + * @param target The player target + * @param serverFrom The server initiating the request + */ + public void handleInviteRequest(String sender, String target, String serverFrom) + { + Player player = Bukkit.getPlayer(target); + if (player == null) + { + //Shouldn't happen, as a "findPLayer" packet will be sent out first. + return; + } + _players.put(player.getUniqueId(), player.getName()); + inviteTo(player.getUniqueId(), sender, sender, serverFrom); + Lang.INVITE_RECEIVED.send(player, sender); + sendAcceptOrDeny(player, sender); + } + + /** + * Handles the response returned via redis when an invite is handled cross server + * + * @param sender The player sender + * @param target The player target + * @param targetUUID The player targets UUID + * @param response The response to this invite + */ + public void handleInviteResponse(String sender, String target, UUID targetUUID, InviteResponse response) + { + remove(sender, targetUUID); + Player player = Bukkit.getPlayer(sender); + if (player == null) + { + return; + } + String message = F.main("Party", response.format(target)); + + Party party = _plugin.getParty(sender); + String partyName = sender; + if(party != null) + { + partyName = party.getName(); + } + + switch (response) + { + case ACCEPTED: + addToPendingJoin(targetUUID, partyName); + break; + case EXPIRED: + case DENIED: + if (party == null) + { + player.sendMessage(message); + return; + } + party.sendMessage(message); + break; + } + } + + /** + * Remove all references tied with this player + * + * @param player The player's UUID + */ + public void removeAll(UUID player) + { + _players.remove(player); + _invitedBy.remove(player); + _activeInvites.remove(player); + } + + /** + * Get the name of the party who is awaiting this player to join + * + * @param player The player's UUID + * @return The name of the awaiting party. + */ + public String getPartyWaiting(UUID player) + { + return _awaitingJoin.get(player); + } + + /** + * Remove the party reference that invited this player + * + * @param player The player's UUID + */ + public void removeFromWaiting(UUID player) + { + _awaitingJoin.remove(player); + } + + /** + * Add a player to the active invites map + * + * @param player The player who has been invited + * @param party The party name + */ + public void inviteTo(UUID player, String invitedBy, String party, String server) + { + addToInvite(player, invitedBy, party, server); + _tasks.put(player, new BukkitRunnable() + { + @Override + public void run() + { + if (!isInvitedTo(player, party)) + { + cancel(); + return; + } + InviteData data = remove(party, player); + Player possible = Bukkit.getPlayer(player); + String playerName = _players.remove(player); + if (possible != null) + { + playerName = possible.getName(); + possible.sendMessage(F.main("Party", "Your invite to " + F.name(party) + "'s party has expired")); + } + sendExpired(data.getServerFrom(), party, playerName, player); + } + }.runTaskLater(_plugin.getPlugin(), 20 * 60)); + } + + /** + * Checks to see if a player is invited to a specific party + * + * @param player The player who we want to check against + * @param party The name of the party to check + * @return true if the player has an invite to the specific party + */ + public boolean isInvitedTo(UUID player, String party) + { + if (!_activeInvites.containsKey(player)) + { + return false; + } + List dataList = _activeInvites.get(player); + for (InviteData data : dataList) + { + if (data.getInvitedTo().equalsIgnoreCase(party)) + { + return true; + } + } + return false; + } + + /** + * Remove a player's invite to a certain party + * + * @param party The name of the party + * @param invited The UUID of the player + */ + public InviteData remove(String party, UUID invited) + { + List data = _activeInvites.get(invited); + InviteData temp = null; + for (InviteData inviteData : data) + { + if (inviteData.getInvitedTo().equalsIgnoreCase(party)) + { + temp = inviteData; + break; + } + } + if (temp != null) + { + data.remove(temp); + } + _activeInvites.put(invited, data); + return temp; + } + + /** + * Stop the player's expired task from running + * + * @param player The UUID of the player + */ + public void cancelTask(UUID player) + { + BukkitTask task = _tasks.remove(player); + if(task != null) + { + task.cancel(); + } + } + + /** + * Retrieves all invites currently pending for a specific player + * @param player The player + * @return All his current pending invites + */ + public Collection getAllInvites(Player player) + { + return _activeInvites.get(player.getUniqueId()); + } + + /** + * Send an "ExpiredPartyInvite" redis message + * + * @param server The server to + * @param party The party who initiated the request (can also be a player's name) + * @param playerName The name of the invited player + * @param player The invited player's UUID + */ + private void sendExpired(String server, String party, String playerName, UUID player) + { + _plugin.getRedisManager().publish(server, RedisMessageType.INVITE_PLAYER_RESPONSE, party, playerName, player.toString(), InviteResponse.EXPIRED.name()); + } + + /** + * Marks this player as having an accepted invite + * This is used to control the creation of single player parties, and makes sure a party is created ONLY if a player joins the server successfully. + * + * @param player The UUID of the player + * @param party The name of the party + */ + private void addToPendingJoin(UUID player, String party) + { + _awaitingJoin.put(player, party); + } + + /** + * Add a pending invite for a player + * + * @param invited The invited players UUUD + * @param invitedBy The person who invited him + * @param party The name of the party invited to + * @param server The server the request is from + */ + private void addToInvite(UUID invited, String invitedBy, String party, String server) + { + List inviteDatas = _activeInvites.get(invited); + if (inviteDatas == null) + { + inviteDatas = Lists.newArrayList(); + } + InviteData inviteData = new InviteData(party, server); + inviteDatas.add(inviteData); + _invitedBy.put(invited, invitedBy); + _activeInvites.put(invited, inviteDatas); + } + + /** + * Sends a Text Componoent clickable message to a player for easier quick responses to invites + * + * @param player The player who received the invite + * @param arg The name of the inviting party + */ + public void sendAcceptOrDeny(Player player, String arg) + { + TextComponent textComponent = new TextComponent(F.main("Party", "Reply: ")); + + TextComponent accept = new TextComponent("ACCEPT"); + accept.setColor(ChatColor.GREEN); + accept.setBold(true); + accept.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/partyaccept " + arg)); + accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{ + new TextComponent("Click to join " + F.name(arg) + "'s party") + })); + + textComponent.addExtra(accept); + textComponent.addExtra(" "); + + TextComponent deny = new TextComponent("DENY"); + deny.setColor(ChatColor.RED); + deny.setBold(true); + deny.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/partydeny " + arg)); + deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{ + new TextComponent("Click to decline joining " + F.name(arg) + "'s party") + })); + + textComponent.addExtra(deny); + textComponent.addExtra(" "); + + TextComponent view = new TextComponent("VIEW"); + view.setColor(ChatColor.YELLOW); + view.setBold(true); + view.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/openinvitesmenu")); + view.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{ + new TextComponent("Click to view all pending invites.") + })); + + textComponent.addExtra(view); + + player.spigot().sendMessage(textComponent); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java new file mode 100644 index 000000000..9226ce9c6 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyJoinManager.java @@ -0,0 +1,125 @@ +package mineplex.core.party.manager; + +import com.google.common.collect.Lists; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.constants.JoinResponseReason; +import mineplex.core.party.redis.RedisMessageType; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * Manages allocating slots for parties to join + */ +public class PartyJoinManager +{ + + private final PartyManager _plugin; + private final int _maxPLayers; + private final List _transferring; + + public PartyJoinManager(PartyManager plugin) + { + _plugin = plugin; + _maxPLayers = plugin.getPlugin().getServer().getMaxPlayers(); + _transferring = Lists.newArrayList(); + } + + /** + * Initiates a request to join a server for a specific party + * + * @param server The desired server + * @param party The requesting party + */ + public void requestServerJoin(String server, Party party) + { + boolean canJoinFull = true; + List players = party.getMembers().stream().map(Bukkit::getPlayer).collect(Collectors.toList()); + for (Player player : players) + { + Rank rank = _plugin.getClientManager().Get(player).GetRank(); + if (rank == Rank.ALL) + { + canJoinFull = false; + break; + } + } + _plugin.getRedisManager().publish(server, RedisMessageType.PREJOIN_SERVER_REQUEST, + _plugin.getServerName(), party.getOwner(), "" + party.getMembers().size(), "" + canJoinFull); + } + + /** + * Manages a received request + * + * @param serverFrom The server who initiated the request + * @param partySize The size of the party + * @param initiator The player who sent the request + * @param canJoinFull true if the party contains all donators or staff (full joining able players) + */ + public void handleJoinRequest(String serverFrom, int partySize, String initiator, boolean canJoinFull) + { + int currentPlayers = UtilServer.getPlayers().length; + if (currentPlayers >= _maxPLayers || (currentPlayers + partySize) >= _maxPLayers) + { + //Max number of people on. + if (!canJoinFull) + { + _plugin.getRedisManager().publish(serverFrom, RedisMessageType.PREJOIN_SERVER_RESPONSE, initiator, JoinResponseReason.CANNOT_JOIN_FULL.name(), _plugin.getServerName()); + return; + } + } + + _plugin.getRedisManager().publish(serverFrom, RedisMessageType.PREJOIN_SERVER_RESPONSE, initiator, JoinResponseReason.SUCCESS.name(), _plugin.getServerName()); + + } + + /** + * Manages a received response + * + * @param playerSender The player who sent the request + * @param server The server responding + * @param reason The reason for the response + */ + public void handleJoinResponse(String playerSender, String server, JoinResponseReason reason) + { + Player player = Bukkit.getPlayer(playerSender); + if (player == null) + { + return; + } + Party party = _plugin.getParty(player); + if (party == null) + { + return; + } + if (reason != JoinResponseReason.SUCCESS) + { + party.sendMessage(reason.getMessage()); + return; + } + party.sendMessage(F.main("Party", "Transferring servers...")); + _plugin.getRedisManager().sendPartyInfo(server, party); + _transferring.addAll(party.getMembersByUUID()); + } + + /** + * Retrieve whether or not the player is currently transferring servers + * We wont need this information again, so calling a remove works fine. + * + * @param player The player + * @return true if the player is transferring servers + */ + public boolean isTransferring(Player player) + { + return _transferring.remove(player.getUniqueId()); + } + + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyMethodManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyMethodManager.java new file mode 100644 index 000000000..4d2a5c21e --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyMethodManager.java @@ -0,0 +1,337 @@ +package mineplex.core.party.manager; + +import com.google.common.collect.Lists; +import mineplex.core.common.util.F; +import mineplex.core.party.Lang; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.constants.PartyRemoveReason; +import mineplex.core.party.ui.Menu; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +/** + * Contains all methods used by the internal UI system + */ +public class PartyMethodManager +{ + + private PartyManager _plugin; + + public PartyMethodManager(PartyManager plugin) + { + _plugin = plugin; + } + + /** + * Invite a player to either a new party or existing one + * + * @param caller The player who initiated the request + * @param target The player's target + */ + public void invite(Player caller, String target) + { + Player possible = Bukkit.getPlayer(target); + Party party = _plugin.getParty(caller); + + if(target.equalsIgnoreCase(caller.getName())) + { + caller.sendMessage(F.main("Party", "You cannot invite yourself!")); + return; + } + + boolean can = Bukkit.getMaxPlayers() >= _plugin.getPlugin().getServer().getOnlinePlayers().size(); + if(!can) + { + Lang.SERVER_FULL.send(caller); + return; + } + + //Same Server + if (possible != null) + { + + if(!_plugin.getPreferencesManager().Get(possible).PartyRequests) + { + caller.sendMessage(F.main("Party> ", F.name(target) + " is not accepting invites at this time.")); + return; + } + + if (party == null) + { + if(_plugin.getParty(target) != null) + { + Lang.PLAYER_IN_DIFFERENT_PARTY.send(caller, target); + return; + } + if(_plugin.getInviteManager().isInvitedTo(possible.getUniqueId(), caller.getName())) + { + Lang.ALREADY_INVITED.send(caller, target); + return; + } + Lang.INVITE_SUCCESS_PLAYER.send(caller, possible.getName()); + } else + { + if(!party.getOwner().equalsIgnoreCase(caller.getName())) + { + Lang.NOT_OWNER.send(caller); + return; + } + if(_plugin.getInviteManager().isInvitedTo(possible.getUniqueId(), party.getName())) + { + Lang.ALREADY_INVITED.send(caller, target); + return; + } + if(party.getMembers().contains(target)) + { + Lang.ALREADY_MEMBER.send(caller, target); + return; + } + if(_plugin.getParty(target) != null) + { + Lang.PLAYER_IN_DIFFERENT_PARTY.send(caller, target); + return; + } + if(party.getMembers().size() >= party.getSize()) + { + Lang.PARTY_FULL.send(caller); + return; + } + + Lang.SUCCESS_INVITE.send(party, caller.getName(), target); + } + + UUID uuid = possible.getUniqueId(); + + Lang.INVITE_RECEIVED.send(possible, caller.getName(), caller.getName()); + + _plugin.getInviteManager().inviteTo(uuid, caller.getName(), caller.getName(), _plugin.getServerName()); + + _plugin.getInviteManager().sendAcceptOrDeny(possible, caller.getName()); + return; + } + //Not on the same server + _plugin.getRedisManager().findAndInvite(target, caller.getName()); + } + + /** + * Responds to a pending invite + * + * @param caller The player who initiated the request + * @param target The player's target + * @param accept true If the player has accepted the invite + */ + public void respondToInvite(Player caller, String target, boolean accept) + { + if(_plugin.getParty(caller) != null) + { + Lang.ALREADY_IN.send(caller); + caller.sendMessage(F.main("Party", "Please leave your party before joining!")); + return; + } + + PartyInviteManager inviteManager = _plugin.getInviteManager(); + + if (!inviteManager.isInvitedTo(caller.getUniqueId(), target)) + { + //He isn't invited to this party. + Lang.NOT_INVITED.send(caller, target); + return; + } + if(!accept) + { + caller.sendMessage(F.main("Party", "You have denied the invite to " + F.name(target)) + "'s party."); + } + inviteManager.respondToInvite(caller, target, accept); + } + + /** + * Kicks a player from the callers party + * + * @param caller The player who initiated the request + * @param target The player's target + */ + public void forceRemove(Player caller, String target) + { + Party party = _plugin.getParty(caller); + + if (party == null) + { + Lang.NO_PARTY.send(caller); + return; + } + + if (!party.getOwner().equalsIgnoreCase(caller.getName())) + { + Lang.NOT_OWNER.send(caller); + return; + } + + Player playerTarget = Bukkit.getPlayerExact(target); + + if (playerTarget == null) + { + Lang.NOT_MEMBER.send(caller, target); + return; + } + + Party targetParty = _plugin.getParty(playerTarget); + + if (targetParty == null ||!party.getMembers().contains(target)) + { + Lang.NOT_MEMBER.send(caller, target); + return; + } + + removeFromParty(playerTarget.getUniqueId(), PartyRemoveReason.KICKED); + + Lang.REMOVE_PLAYER_KICK.send(targetParty); + } + + /** + * Leaves the players current party if he is in one + * + * @param caller The player who wishes to leave his party + */ + public void leaveParty(Player caller) + { + Party party = _plugin.getParty(caller); + + if (party == null) + { + Lang.NO_PARTY.send(caller); + return; + } + + removeFromParty(caller.getUniqueId(), PartyRemoveReason.LEFT); + Lang.LEFT.send(caller); + } + + /** + * Disbands a players current party, assuming he is the leader + * + * @param caller The player who wishes to disband his party + */ + public void disband(Player caller) + { + Party party = _plugin.getParty(caller); + + if (party == null) + { + Lang.NO_PARTY.send(caller); + return; + } + + if (!party.getOwner().equalsIgnoreCase(caller.getName())) + { + Lang.NOT_OWNER.send(caller); + return; + } + caller.sendMessage(F.main("Party", "You have disbanded your party.")); + disbandParty(party); + } + + public void addToParty(UUID uuid, Party party) + { + _plugin.getPlayerParties().put(uuid, party); + Player player = Bukkit.getPlayer(uuid); + party.onPlayerAdd(player.getName()); + if(!party.getMembersByUUID().contains(uuid)) + { + party.getMembersByUUID().add(uuid); + } + } + + public void addToPartyOnTransfer(UUID uuid, Party party) + { + _plugin.getPlayerParties().put(uuid, party); + } + + public void addToParty(Player player, Party party) + { + addToParty(player.getUniqueId(), party); + } + + public void removeForTransfer(UUID uuid) + { + Party party = _plugin.getPlayerParties().remove(uuid); + if(party == null) + { + return; + } + String player = Bukkit.getPlayer(uuid).getName(); + party.onPlayerRemove(player, PartyRemoveReason.OTHER); + } + + public void removeFromParty(UUID uuid, PartyRemoveReason reason) + { + Party party = _plugin.getPlayerParties().remove(uuid); + if(party == null) + { + return; + } + + Player player = Bukkit.getPlayer(uuid); + + if(player.getOpenInventory() != null) + { + if (Menu.get(player.getUniqueId()) != null) + { + player.closeInventory(); + Menu.remove(player.getUniqueId()); + } + } + + if(reason == PartyRemoveReason.DISBANDED_BY_OWNER) + { + return; + } + party.getMembers().remove(player.getName()); + party.getMembersByUUID().remove(uuid); + party.onPlayerRemove(player.getName(), reason); + + int size = party.getMembers().size(); + if(size <= 1) + { + if(size == 0) + { + _plugin.removeParty(party); + return; + } + _plugin.getPlayerParties().remove(Bukkit.getPlayerExact(party.getMembers().get(0)).getUniqueId()); + party.onPlayerRemove(party.getMembers().get(0), PartyRemoveReason.DISBANDED); + _plugin.removeParty(party); + } + } + + public void removeFromParty(Player player, PartyRemoveReason reason) + { + removeFromParty(player.getUniqueId(), reason); + } + + public void disbandParty(Party party) + { + List members = Lists.newArrayList(party.getMembersByUUID()); + Lang.DISBANDED_BY_OWNER.send(party); + members.stream().forEach(player -> removeFromParty(player, PartyRemoveReason.DISBANDED_BY_OWNER)); + party.getMembers().clear(); + party.getMembersByUUID().clear(); + _plugin.removeParty(party); + } + + public void transferOwner(String newOwner, String oldOwner) + { + Party party = _plugin.getParties().remove(oldOwner); + if(party == null) + { + return; + } + _plugin.getParties().put(newOwner, party); + party.setOwner(newOwner); + party.getMembers().remove(oldOwner); + party.getMembers().add(oldOwner); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyRedisManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyRedisManager.java new file mode 100644 index 000000000..d657d3214 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/manager/PartyRedisManager.java @@ -0,0 +1,250 @@ +package mineplex.core.party.manager; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import mineplex.core.common.util.F; +import mineplex.core.party.Lang; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.constants.InviteResponse; +import mineplex.core.party.constants.JoinResponseReason; +import mineplex.core.party.event.PartyDataReceivedEvent; +import mineplex.core.party.redis.PartyRedisListener; +import mineplex.core.party.redis.RedisMessageType; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static mineplex.core.party.redis.RedisMessageType.INVITE_PLAYER_REQUEST; +import static mineplex.core.party.redis.RedisMessageType.PARTY_INFO; + +/** + * Redis system for Parties + */ +public class PartyRedisManager +{ + protected final Gson GSON = new GsonBuilder().create(); + + protected static final String CHANNEL_BASE = "party-pubsub"; + protected static final String FIND_PLAYERS_CHANNEL = "party-player-finder"; + private final Map TASKS = Maps.newHashMap(); + + private final PartyManager _plugin; + private final JedisPool _writePool; + private final String _channel; + private final String _serverName; + + public PartyRedisManager(PartyManager plugin, String serverName, JedisPool writePool, JedisPool readPool) + { + _plugin = plugin; + _serverName = serverName; + _writePool = writePool; + _channel = CHANNEL_BASE + "-" + serverName; + + plugin.runAsync(() -> { + try (Jedis jedis = readPool.getResource()) + { + jedis.subscribe(new PartyRedisListener(this), _channel, FIND_PLAYERS_CHANNEL); + } + }); + } + + /** + * Send a message to a specific server + * + * @param server The destination server + * @param messageType The message to send + * @param args The arguments accompanying the request + */ + public void publish(String server, RedisMessageType messageType, String... args) + { + _plugin.runAsync(() -> { + try (Jedis jedis = _writePool.getResource()) + { + jedis.publish(CHANNEL_BASE + "-" + server, messageType.name() + "@" + messageType.format(args)); + } + }); + } + + /** + * Handle a message received on this server + * + * @param messageType The type of message received + * @param message The contents of the request + */ + public void handle(RedisMessageType messageType, String message) + { + if (messageType == PARTY_INFO) + { + handlePartyInfo(message); + return; + } + String[] contents = message.split(","); + if (contents.length < 3) + { + return; + } + String first = contents[0]; + String second = contents[1]; + String third = contents[2]; + Bukkit.getScheduler().runTask(_plugin.getPlugin(), () -> { + switch (messageType) + { + case INVITE_PLAYER_REQUEST: + _plugin.getInviteManager().handleInviteRequest(second, third, first); + break; + + case INVITE_PLAYER_RESPONSE: + _plugin.getInviteManager().handleInviteResponse(first, second, UUID.fromString(third), InviteResponse.valueOf(contents[3].toUpperCase())); + break; + + case PLAYER_FIND_REQUEST: + Player player = Bukkit.getPlayer(second); + + if (player == null) + { + return; + } + + publish(first, RedisMessageType.PLAYER_FIND_RESPONSE, _serverName, player.getName(), player.getUniqueId().toString(), third); + break; + + case PLAYER_FIND_RESPONSE: + UUID uuid = UUID.fromString(third); + BukkitTask task = TASKS.remove(second); + + if (task != null) + { + task.cancel(); + } + + Player inviter = Bukkit.getPlayerExact(contents[3]); + if (_plugin.getInviteManager().isInvitedTo(uuid, inviter.getName())) + { + Lang.ALREADY_INVITED.send(inviter, second); + return; + } + if (_plugin.getParty(inviter) == null) + { + Lang.INVITE_SUCCESS_PLAYER.send(inviter, second); + } else + { + Lang.SUCCESS_INVITE.send(_plugin.getParty(inviter), inviter.getName(), second); + } + _plugin.getInviteManager().inviteTo(uuid, inviter.getName(), inviter.getName(), _plugin.getServerName()); + publish(first, INVITE_PLAYER_REQUEST, _serverName, inviter.getName(), second); + break; + + case PREJOIN_SERVER_REQUEST: + _plugin.getJoinManager().handleJoinRequest(first, Integer.valueOf(third), second, Boolean.valueOf(contents[3])); + break; + + case PREJOIN_SERVER_RESPONSE: + _plugin.getJoinManager().handleJoinResponse(first, third, JoinResponseReason.valueOf(second.toUpperCase())); + break; + } + }); + + } + + /** + * Initiates inviting a player who is no on the same server + * + * @param player The player target + * @param sender The sending player + */ + public void findAndInvite(String player, String sender) + { + Bukkit.getPlayerExact(sender).sendMessage(F.main("Party", "Locating " + F.elem(player) + "...")); + TASKS.put(player, new BukkitRunnable() + { + @Override + public void run() + { + TASKS.remove(player); + Player senderPlayer = Bukkit.getPlayerExact(sender); + if (senderPlayer == null) + { + cancel(); + return; + } + if (Bukkit.getPlayerExact(player) != null) + { + cancel(); + return; + } + senderPlayer.sendMessage(F.main("Party", "Could not locate " + F.elem(player) + ".")); + } + }.runTaskLater(_plugin.getPlugin(), 20L * 5)); + + _plugin.runAsync(() -> { + try (Jedis jedis = _writePool.getResource()) + { + jedis.publish(FIND_PLAYERS_CHANNEL, RedisMessageType.PLAYER_FIND_REQUEST.format(_serverName, player, sender)); + } + }); + } + + /** + * Serializes and sends a party to another server + * + * @param server The destination server + * @param party The party to be sent + */ + public void sendPartyInfo(String server, Party party) + { + publish(server, PARTY_INFO, GSON.toJson(party)); + List members = party.getMembers(); + party.getMembersByUUID().forEach(uuid -> _plugin.getMethodManager().removeForTransfer(uuid)); + members.stream().map(Bukkit::getPlayer).forEach(player1 -> + { + player1.leaveVehicle(); + player1.eject(); + _plugin.getPortal().sendPlayerToServer(player1, server, true); + }); + _plugin.removeParty(party); + } + + /** + * Deserialize and store a received party's information + * @param json + */ + public void handlePartyInfo(String json) + { + new BukkitRunnable() + { + @Override + public void run() + { + Party party = GSON.fromJson(json, Party.class); + _plugin.addParty(party); + party.getMembersByUUID().forEach(s -> _plugin.getMethodManager().addToPartyOnTransfer(s, party)); + Bukkit.getServer().getPluginManager().callEvent(new PartyDataReceivedEvent(party)); + } + }.runTaskLater(_plugin.getPlugin(), 10L); + } + + /** + * @return This servers name + */ + public String getServerName() + { + return _serverName; + } + + /** + * @return The channel constant for finding players + */ + public String getFinder() + { + return FIND_PLAYERS_CHANNEL; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyRedisListener.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyRedisListener.java new file mode 100644 index 000000000..f4c3b4d20 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyRedisListener.java @@ -0,0 +1,30 @@ +package mineplex.core.party.redis; + +import mineplex.core.party.manager.PartyRedisManager; +import redis.clients.jedis.JedisPubSub; + +/** + * Handles incoming messages into the Party Redis System + */ +public class PartyRedisListener extends JedisPubSub +{ + + private final PartyRedisManager _redisManager; + + public PartyRedisListener(PartyRedisManager redisManager) + { + _redisManager = redisManager; + } + + @Override + public void onMessage(String channel, String message) + { + if(channel.equalsIgnoreCase(_redisManager.getFinder())) + { + _redisManager.handle(RedisMessageType.PLAYER_FIND_REQUEST, message); + return; + } + RedisMessageType type = RedisMessageType.valueOf(message.split("@")[0].toUpperCase()); + _redisManager.handle(type, message.split("@")[1]); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisMessageType.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisMessageType.java new file mode 100644 index 000000000..341e121a6 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisMessageType.java @@ -0,0 +1,59 @@ +package mineplex.core.party.redis; + +/** + * Messages sent within the redis messaging system + * And their corresponding arguments + */ +public enum RedisMessageType +{ + + //Message: SERVER_FROM,PLAYER_TARGET,PLAYER_SENDER + PLAYER_FIND_REQUEST(1, "{0},{1},{2}"), + //Message: SERVER_ON,PLAYER_TARGET_NAME,PLAYER_TARGET_UUID,PLAYER_SENDER + PLAYER_FIND_RESPONSE(2, "{0},{1},{2},{3}"), + + //Message: SERVER_FROM,PLAYER_SENDER,PLAYER_TARGET + INVITE_PLAYER_REQUEST(3, "{0},{1},{2}"), + //Message: PLAYER_SENDER,PLAYER_TARGET_NAME,PLAYER_TARGET_UUID,RESPONSE + INVITE_PLAYER_RESPONSE(4, "{0},{1},{2},{3}"), + + //Message: SERVER_FROM,PLAYER_INITIATING,PARTY_SIZE,_CAN_JOIN_FULL + PREJOIN_SERVER_REQUEST(5, "{0},{1},{2},{3}"), + //Message: PLAYER_INITIATING,REASON,SERVER + PREJOIN_SERVER_RESPONSE(6, "{0},{1},{2}"), + + //Message: JSON Party + PARTY_INFO(7, "{0}"), + TEST_CONN(8, "{0}") + ; + + private int _id; + private String _contents; + + RedisMessageType(int id, String contents) + { + _id = id; + _contents = contents; + } + + public int getId() + { + return _id; + } + + /** + * Format this message + * @param args The contents to be sent with this message + * @return A formatted message + */ + public String format(String... args) + { + String message = _contents; + for(int i = 0; i < args.length; i++) + { + message = message.replace("{" + i + "}", args[i]); + } + return message; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisPartyData.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisPartyData.java deleted file mode 100644 index cec09d728..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisPartyData.java +++ /dev/null @@ -1,33 +0,0 @@ -package mineplex.core.party.redis; - -import mineplex.core.party.Party; -import mineplex.serverdata.commands.ServerCommand; - -public class RedisPartyData extends ServerCommand -{ - private String[] _players; - private String _leader; - private String _previousServer; - - public RedisPartyData(Party party, String previousServer) - { - _players = party.GetPlayers().toArray(new String[0]); - _leader = party.GetLeader(); - _previousServer = previousServer; - } - - public String getPreviousServer() - { - return _previousServer; - } - - public String[] getPlayers() - { - return _players; - } - - public String getLeader() - { - return _leader; - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisPartyHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisPartyHandler.java deleted file mode 100644 index e88aeb675..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/RedisPartyHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package mineplex.core.party.redis; - -import mineplex.core.party.Party; -import mineplex.core.party.PartyManager; -import mineplex.serverdata.commands.CommandCallback; -import mineplex.serverdata.commands.ServerCommand; - -public class RedisPartyHandler implements CommandCallback -{ - private PartyManager _partyManager; - - public RedisPartyHandler(PartyManager partyManager) - { - _partyManager = partyManager; - } - - @Override - public void run(ServerCommand command) - { - final RedisPartyData data = (RedisPartyData) command; - - _partyManager.getPlugin().getServer().getScheduler().runTask(_partyManager.getPlugin(), new Runnable() - { - public void run() - { - _partyManager.addParty(new Party(_partyManager, data)); - } - }); - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Button.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Button.java new file mode 100644 index 000000000..fe5d4468d --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Button.java @@ -0,0 +1,45 @@ +package mineplex.core.party.ui; + +import mineplex.core.party.PartyManager; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * An abstract class for managing buttons inside of menus + */ +public abstract class Button +{ + + private ItemStack _item; + private PartyManager _plugin; + + public Button(ItemStack item, PartyManager plugin) + { + this._item = item; + _plugin = plugin; + } + + /** + * The method called when a players clicks the slot + * + * @param player The player who clicked + */ + public abstract void onClick(Player player, ClickType clickType); + + public ItemStack getItemStack() + { + return _item; + } + + public void setItemStack(ItemStack item) + { + this._item = item; + } + + public PartyManager getPlugin() + { + return _plugin; + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Menu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Menu.java new file mode 100644 index 000000000..90d8ef852 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Menu.java @@ -0,0 +1,272 @@ +package mineplex.core.party.ui; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.button.IconButton; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * A class to manage dynamic creation of GUI's + */ +public abstract class Menu +{ + + protected static final Button PANE = new IconButton(new ItemBuilder(Material.STAINED_GLASS_PANE) + .setTitle(" ") + .setData(DyeColor.LIGHT_BLUE.getWoolData()) + .build(), null); + + protected static final Button PURCHASE_MORE_SLOTS = new IconButton(new ItemBuilder(Material.REDSTONE_BLOCK) + .setTitle(C.cRed + C.Bold + "Locked!") + .setLore(" ", C.cGray + "Purchase a rank @ mineplex.com/shop", C.cGray + "Purchasing a rank increases your", C.cGray + "party size to allow 10 people!") + .build(), null); + + protected static final Button[] EMPTY = new Button[54]; + protected static Map MENUS = new HashMap<>(); + private String _name; + protected Button[] _buttons; + protected PartyManager _plugin; + + public Menu(String name, PartyManager plugin) + { + _name = name; + _buttons = EMPTY; + _plugin = plugin; + } + + public static Menu get(UUID name) + { + return MENUS.get(name); + } + + /** + * Create an icon (no click action) + * + * @param item The itemstack ti display + * @return The created button + */ + protected Button create(ItemStack item) + { + return new IconButton(item, _plugin); + } + + public String getName() + { + return ChatColor.translateAlternateColorCodes('&', _name); + } + + public Button[] addPanes(Button[] buttons) + { + for (int i = 0; i < 9; i++) + { + if (buttons[i] == null) + { + buttons[i] = PANE; + } + + if(buttons.length == 9) + { + continue; + } + + if (buttons[i + buttons.length - 9] == null) + { + buttons[i + buttons.length - 9] = PANE; + } + + if (i == 0 || i == 8) + { + for (int a = 9; a < buttons.length; a += 9) + { + buttons[i + a] = PANE; + } + } + } + return buttons; + } + + /** + * Open and setup the inventory for the player to view + * Store a reference to it inside a map for retrieving later + * + * @param player The player who we wish to show the GUI to + */ + public void open(Player player) + { + setButtons(setUp(player)); + + if (MENUS.get(player.getUniqueId()) != null) + { + MENUS.remove(player.getUniqueId()); + } + + MENUS.put(player.getUniqueId(), this); + + int size = (_buttons.length + 8) / 9 * 9; + Inventory inventory = Bukkit.createInventory(player, size, getName()); + + for (int i = 0; i < _buttons.length; i++) + { + if (_buttons[i] == null) + { + continue; + } + + ItemStack item = _buttons[i].getItemStack(); + + inventory.setItem(i, item); + } + player.openInventory(inventory); + } + + /** + * Set up the GUI with buttons + * + * @return The setup button array + */ + protected abstract Button[] setUp(Player player); + + public Button[] getButtons() + { + return _buttons; + } + + public void setButtons(Button[] buttons) + { + _buttons = buttons; + } + + /** + * Retrieve the button based off the slot + * + * @param slot The slot in the inventory + * @return The button corresponding to that slot + */ + public Button getButton(int slot) + { + try + { + return _buttons[slot]; + } catch (ArrayIndexOutOfBoundsException e) + { + //There isn't a button there, so no need to throw an error + //e.printStackTrace(); + return null; + } + } + + /** + * Replace a button, or create a new button dynamically + * Update the players GUI + * + * @param slot The slot to set the new button + * @param button The reference to the button + * @param player The player whose GUI we'll be updating + */ + public void setButton(int slot, Button button, Player player) + { + try + { + _buttons[slot] = button; + } catch (ArrayIndexOutOfBoundsException ignored) + { + ignored.printStackTrace(); + } + update(player); + } + + /** + * Refresh the players view, allows to change what the player sees, without opening and closing the GUI + * + * @param player The player whose view you wish to update + */ + public void update(Player player) + { + InventoryView view = player.getOpenInventory(); + + if (view == null) + { + return; + } + + if (!view.getTitle().equalsIgnoreCase(getName())) + { + return; + } + + Inventory inventory = view.getTopInventory(); + for (int i = 0; i < _buttons.length; i++) + { + if (_buttons[i] == null) + { + continue; + } + + ItemStack item = _buttons[i].getItemStack(); + + inventory.setItem(i, item); + } + } + + /** + * Reset this players current menu's buttons and refresh the page + * + * @param player The player whose view you wish to update + */ + public void resetAndUpdate(Player player) + { + InventoryView view = player.getOpenInventory(); + + if (view == null) + { + return; + } + + if (!view.getTitle().equalsIgnoreCase(getName())) + { + return; + } + + Inventory inventory = view.getTopInventory(); + Button[] buttons = setUp(player); + for (int i = 0; i < buttons.length; i++) + { + if (buttons[i] == null) + { + continue; + } + + ItemStack item = buttons[i].getItemStack(); + + inventory.setItem(i, item); + } + } + + + public void setTitle(String title) + { + _name = title; + } + + public void onClose(Player player) + { + MENUS.remove(player.getUniqueId()); + } + + public static Menu remove(UUID uniqueId) + { + return MENUS.remove(uniqueId); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/MenuListener.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/MenuListener.java new file mode 100644 index 000000000..fb28a5a7c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/MenuListener.java @@ -0,0 +1,57 @@ +package mineplex.core.party.ui; + +import mineplex.core.party.ui.button.PartyMemberIcon; +import mineplex.core.party.ui.menus.PartyOwnerMenu; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + +/** + * Listener for the Menu system + */ +public class MenuListener implements Listener +{ + + @EventHandler + public void onClick(InventoryClickEvent event) + { + String name = event.getInventory().getName(); + Player player = (Player) event.getWhoClicked(); + Menu gui = Menu.get(player.getUniqueId()); + + if (gui == null) + { + return; + } + + if (!gui.getName().equalsIgnoreCase(name)) + { + return; + } + + Button button = gui.getButton(event.getRawSlot()); + + event.setCancelled(true); + event.setResult(Event.Result.DENY); + + if (button == null) + { + return; + } + + if(button instanceof PartyMemberIcon) + { + if(!(gui instanceof PartyOwnerMenu)) + { + return; + } + ((PartyMemberIcon) button).onClick(player, event.getCurrentItem()); + return; + } + + button.onClick(player, event.getClick()); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/IconButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/IconButton.java new file mode 100644 index 000000000..0e80c09cd --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/IconButton.java @@ -0,0 +1,26 @@ +package mineplex.core.party.ui.button; + +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Representation of a purely cosmetic icon + * IE: When clicked, this button does not execute any action + */ +public class IconButton extends Button +{ + + public IconButton(ItemStack item, PartyManager plugin) + { + super(item, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/PartyMemberIcon.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/PartyMemberIcon.java new file mode 100644 index 000000000..5be48d2c9 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/PartyMemberIcon.java @@ -0,0 +1,67 @@ +package mineplex.core.party.ui.button; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.event.PartyMemberKickGUIEvent; +import mineplex.core.party.ui.button.tools.PartyButton; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * The button representing a Party member. + */ +public class PartyMemberIcon extends PartyButton +{ + + private ItemStack _itemStack; + + public PartyMemberIcon(String player, Party party, boolean owner) + { + super(null, party, null); + ItemBuilder builder = new ItemBuilder(Material.SKULL_ITEM, 1, (byte) 3) + .setTitle(C.cYellow + player) + .setPlayerHead(player); + if(owner) + { + builder.addLore(" ", C.cGreenB + "Leader"); + } + _itemStack = builder.build(); + } + + @Override + public ItemStack getItemStack() + { + return _itemStack; + } + + /** + * Called when a player clicks one of the member icons + * + * @param clicker The player who clicked + * @param clicked The itemstack he clicked + */ + public void onClick(Player clicker, ItemStack clicked) + { + if (!getParty().isOwnerKickMode()) + { + return; + } + if(!getParty().getOwner().equalsIgnoreCase(clicker.getName())) + { + return; + } + String name = ChatColor.stripColor(clicked.getItemMeta().getDisplayName()); + UtilServer.getPluginManager().callEvent(new PartyMemberKickGUIEvent(getParty(), name, clicker)); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/LeavePartyButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/LeavePartyButton.java new file mode 100644 index 000000000..1b409a082 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/LeavePartyButton.java @@ -0,0 +1,39 @@ +package mineplex.core.party.ui.button.tools; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Leaves a players current party + */ +public class LeavePartyButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.REDSTONE_BLOCK) + .setTitle(C.cYellow + "Leave Party") + .setLore(" ", C.cRed + "Shift-Left-Click" + C.cGray + " to leave your party.") + .build(); + + public LeavePartyButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if(clickType != ClickType.SHIFT_LEFT) + { + return; + } + getPlugin().getMethodManager().leaveParty(player); + player.closeInventory(); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/PartyButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/PartyButton.java new file mode 100644 index 000000000..463754279 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/PartyButton.java @@ -0,0 +1,26 @@ +package mineplex.core.party.ui.button.tools; + +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import org.bukkit.inventory.ItemStack; + +/** + * A wrapper for all buttons which need to interact with a specific party + */ +public abstract class PartyButton extends Button +{ + + private Party _party; + + public PartyButton(ItemStack itemStack, Party party, PartyManager plugin) + { + super(itemStack, plugin); + _party = party; + } + + public Party getParty() + { + return _party; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/BackButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/BackButton.java new file mode 100644 index 000000000..6ac82bc6a --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/BackButton.java @@ -0,0 +1,34 @@ +package mineplex.core.party.ui.button.tools.invite; + +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.menus.PartyMainMenu; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Sends a player back to the main page + */ +public class BackButton extends Button +{ + + private static ItemStack ITEM = new ItemBuilder(Material.BED) + .setTitle(ChatColor.GRAY + "\u21FD Go Back") + .build(); + + public BackButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + player.closeInventory(); + new PartyMainMenu(getPlugin()).open(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/DenyAllButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/DenyAllButton.java new file mode 100644 index 000000000..e39faaca2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/DenyAllButton.java @@ -0,0 +1,35 @@ +package mineplex.core.party.ui.button.tools.invite; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.menus.PartyInvitesMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Deny's all invites currently pending + */ +public class DenyAllButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.REDSTONE_BLOCK) + .setTitle(C.cRed + "Delete all Invites") + .setLore(" ", C.cGray + "This will remove all pending invites.") + .build(); + + public DenyAllButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + getPlugin().getInviteManager().getAllInvites(player).forEach(inviteData -> getPlugin().getMethodManager().respondToInvite(player, inviteData.getInvitedTo(), false)); + new PartyInvitesMenu(getPlugin()).open(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/FilterButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/FilterButton.java new file mode 100644 index 000000000..2a2e5d4ff --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/FilterButton.java @@ -0,0 +1,54 @@ +package mineplex.core.party.ui.button.tools.invite; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.menus.input.InviteFilterMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Filters all current pending invites and displays only the results to a player + */ +public class FilterButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.NAME_TAG) + .setTitle(C.cYellow + "Filter Invites") + .setLore(" ", + C.cGray + "Click to bring up an Anvil GUI", + C.cGray + "where you type and filter", + C.cGray + "Party invites by their name", + " ", + C.cGreen + "Input \"Clear Filter\" to remove the filter") + .build(); + + public FilterButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + public FilterButton(String filter, PartyManager plugin) + { + super(new ItemBuilder(Material.NAME_TAG) + .setTitle(C.cYellow + "Filter Invites") + .setLore(" ", C.cWhite + "Active Filter: " + C.cGreen + filter, " ", + C.cGray + "Click to bring up an Anvil GUI", + C.cGray + "where you type and filter", + C.cGray + "Party invites by their name", + " ", + C.cGreen + "Input \"Clear Filter\" to remove the filter") + .setGlow(true) + .build(), plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + new InviteFilterMenu(getPlugin(), player, null).openInventory(); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/InviteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/InviteButton.java new file mode 100644 index 000000000..edc97abb3 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/InviteButton.java @@ -0,0 +1,42 @@ +package mineplex.core.party.ui.button.tools.invite; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +/** + * Represents an invitation, to which a player can accept or deny + */ +public class InviteButton extends Button +{ + + private String _name; + + public InviteButton(String name, PartyManager plugin) + { + super(new ItemBuilder(Material.SKULL_ITEM) + .setTitle(C.cYellow + name) + .setLore(" ", C.cYellow + "Right-Click " + C.cGray + "to deny the invite", C.cYellow + "Left-Click " + C.cGray + "to accept the invite") + .setData((short) 3) + .setPlayerHead(name) + .build(), plugin); + _name = name; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if(clickType == ClickType.LEFT) + { + getPlugin().getMethodManager().respondToInvite(player, _name, true); + } else if(clickType == ClickType.RIGHT) + { + getPlugin().getMethodManager().respondToInvite(player, _name, false); + } + player.closeInventory(); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/NextPageButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/NextPageButton.java new file mode 100644 index 000000000..1b370911e --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/NextPageButton.java @@ -0,0 +1,49 @@ +package mineplex.core.party.ui.button.tools.invite; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.InviteData; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.button.IconButton; +import mineplex.core.party.ui.menus.PartyInvitesMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * Shows the next page of invites for a player + */ +public class NextPageButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.SIGN).setTitle(C.cYellow + "Next Page").build(); + + private final PartyInvitesMenu _menu; + + public NextPageButton(PartyInvitesMenu menu, PartyManager plugin) + { + super(ITEM, plugin); + _menu = menu; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + _menu.setButton(45, new PrevPageButton(_menu, getPlugin())); + _menu.setCurrentPage(_menu.getCurrentPage() + 1); + if(_menu.getCurrentPage() == _menu.getPagesNeeded()) + { + _menu.setButton(53, new IconButton(new ItemStack(Material.AIR), getPlugin())); + } + List data = _menu.getDataForPage(_menu.getCurrentPage()); + for(int i = 0; i < data.size(); i++) + { + _menu.setButton(i + _menu.getStartingSlot(), new InviteButton(data.get(i).getInvitedTo(), getPlugin())); + } + _menu.update(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/PrevPageButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/PrevPageButton.java new file mode 100644 index 000000000..3400a86cd --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/invite/PrevPageButton.java @@ -0,0 +1,48 @@ +package mineplex.core.party.ui.button.tools.invite; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.InviteData; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.button.IconButton; +import mineplex.core.party.ui.menus.PartyInvitesMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * Shows the previous page of invites for a player + */ +public class PrevPageButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.SIGN).setTitle(C.cYellow + "Previous Page").build(); + + private final PartyInvitesMenu _menu; + + public PrevPageButton(PartyInvitesMenu menu, PartyManager plugin) + { + super(ITEM, plugin); + _menu = menu; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + _menu.setCurrentPage(_menu.getCurrentPage() - 1); + if(_menu.getCurrentPage() == 0) + { + _menu.setButton(45, new IconButton(new ItemStack(Material.AIR), getPlugin())); + } + List data = _menu.getDataForPage(_menu.getCurrentPage()); + for(int i = 0; i < data.size(); i++) + { + _menu.setButton(i + _menu.getStartingSlot(), new InviteButton(data.get(i).getInvitedTo(), getPlugin())); + } + _menu.update(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/main/InvitePlayerButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/main/InvitePlayerButton.java new file mode 100644 index 000000000..162912d7b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/main/InvitePlayerButton.java @@ -0,0 +1,34 @@ +package mineplex.core.party.ui.button.tools.main; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.menus.input.PartyInvitePlayerMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Invites a player to a new party + */ +public class InvitePlayerButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.NAME_TAG) + .setTitle(C.cYellow + "Invite a Player") + .setLore(" ", C.cGray + "Invites a player to join", C.cGray + "you in a new party.") + .build(); + + public InvitePlayerButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + new PartyInvitePlayerMenu(getPlugin(), player, null).openInventory(); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/main/ViewInvitesButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/main/ViewInvitesButton.java new file mode 100644 index 000000000..3ae1c6cf7 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/main/ViewInvitesButton.java @@ -0,0 +1,34 @@ +package mineplex.core.party.ui.button.tools.main; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.menus.PartyInvitesMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Opens the {@code {@link PartyInvitesMenu}} + */ +public class ViewInvitesButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.BOOK) + .setTitle(C.cYellow + "View Invites") + .setLore(" ", C.cGray + "Manage invites to parties.") + .build(); + + public ViewInvitesButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + new PartyInvitesMenu(getPlugin()).open(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/AddPlayerButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/AddPlayerButton.java new file mode 100644 index 000000000..e010089bd --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/AddPlayerButton.java @@ -0,0 +1,36 @@ +package mineplex.core.party.ui.button.tools.owner; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.button.tools.PartyButton; +import mineplex.core.party.ui.menus.input.PartyInvitePlayerMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Sends an invitation to a specific player + */ +public class AddPlayerButton extends PartyButton +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.SIGN) + .setTitle(C.cYellow + "Invite a Player") + .setLore(" ", C.cGray + "Brings up the Inviting Anvil!", C.cGray + "Simply type a player's name", C.cGray + "and click the paper to invite him") + .build(); + + public AddPlayerButton(PartyManager plugin, Party party) + { + super(ITEM, party, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + new PartyInvitePlayerMenu(getPlugin(), player, getParty()).openInventory(); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/DisbandPartyButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/DisbandPartyButton.java new file mode 100644 index 000000000..5c6ad0923 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/DisbandPartyButton.java @@ -0,0 +1,38 @@ +package mineplex.core.party.ui.button.tools.owner; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Disbands a party + */ +public class DisbandPartyButton extends Button +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.BARRIER) + .setTitle(C.cRedB + "Disband your party") + .setLore(" ", C.cGray + "This will erase your party!", C.cRed + "Shift-Right-Click" + C.cGray + " to disband.") + .build(); + + public DisbandPartyButton(PartyManager plugin) + { + super(ITEM, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if(clickType != ClickType.SHIFT_RIGHT) + { + return; + } + getPlugin().getMethodManager().disband(player); + player.closeInventory(); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/KickPlayerButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/KickPlayerButton.java new file mode 100644 index 000000000..03f02fed2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/KickPlayerButton.java @@ -0,0 +1,56 @@ +package mineplex.core.party.ui.button.tools.owner; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.ui.Menu; +import mineplex.core.party.ui.button.tools.PartyButton; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Toggles {@code {@link Party#isOwnerKickMode()}} + */ +public class KickPlayerButton extends PartyButton +{ + + private static final ItemStack ITEM_OFF = new ItemBuilder(Material.IRON_AXE) + .setTitle(C.cYellow + "Kick Players") + .setLore(" ", F.elem("Right-Click") + " to enter " + C.cGreen + "Kick Mode", + C.cGray + "While activated, click on a player's head", C.cGray + "to remove them from the party") + .build(); + + private static final ItemStack ITEM_ON = new ItemBuilder(Material.IRON_AXE) + .setTitle(C.cYellow + "Kick Players") + .setLore(" ", F.elem("Right-Click") + " to leave " + C.cRed + "Kick Mode", + C.cGray + "While activated, click on a player's head", C.cGray + "to remove them from the party") + .setGlow(true) + .build(); + + + public KickPlayerButton(Party party) + { + super(ITEM_OFF, party, null); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + if(clickType != ClickType.RIGHT) + { + return; + } + getParty().setOwnerKickMode(!getParty().isOwnerKickMode()); + if (getParty().isOwnerKickMode()) + { + setItemStack(ITEM_ON); + } else + { + setItemStack(ITEM_OFF); + } + Menu.get(player.getUniqueId()).update(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/SelectServerButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/SelectServerButton.java new file mode 100644 index 000000000..dbbd0a032 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/SelectServerButton.java @@ -0,0 +1,35 @@ +package mineplex.core.party.ui.button.tools.owner; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.event.PartySelectServerEvent; +import mineplex.core.party.ui.button.tools.PartyButton; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Opens the server selection menu + */ +public class SelectServerButton extends PartyButton +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.COMPASS) + .setTitle(C.cYellow + "Select Server") + .setLore(" ", C.cGray + "Brings up the Server Selection GUI") + .build(); + + public SelectServerButton(Party party) + { + super(ITEM, party, null); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + UtilServer.getPluginManager().callEvent(new PartySelectServerEvent(player)); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/TransferOwnerButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/TransferOwnerButton.java new file mode 100644 index 000000000..5d49eae44 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/owner/TransferOwnerButton.java @@ -0,0 +1,36 @@ +package mineplex.core.party.ui.button.tools.owner; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.button.tools.PartyButton; +import mineplex.core.party.ui.menus.input.PartyTransferOwnerMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Transfers ownership of a party to another player + */ +public class TransferOwnerButton extends PartyButton +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.BOOK_AND_QUILL) + .setTitle(C.cYellow + "Transfer Ownership") + .setLore(" ", C.cGray + "Transfers ownership of the party", C.cGray + "to another player", + " ", C.cDRed + "This cannot be undone!") + .build(); + + public TransferOwnerButton(Party party, PartyManager plugin) + { + super(ITEM, party, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + new PartyTransferOwnerMenu(getPlugin(), player, getParty()).openInventory(); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/view/SuggestPlayerButton.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/view/SuggestPlayerButton.java new file mode 100644 index 000000000..90c2aa8dc --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/tools/view/SuggestPlayerButton.java @@ -0,0 +1,35 @@ +package mineplex.core.party.ui.button.tools.view; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.button.tools.PartyButton; +import mineplex.core.party.ui.menus.input.PlayerSuggestPlayerMenu; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +/** + * Suggest a new player to be invited + */ +public class SuggestPlayerButton extends PartyButton +{ + + private static final ItemStack ITEM = new ItemBuilder(Material.BOOK_AND_QUILL) + .setTitle(C.cYellow + "Suggest Player") + .setLore(" ", C.cGray + "Suggest a player for the owner to invite") + .build(); + + public SuggestPlayerButton(Party party, PartyManager plugin) + { + super(ITEM, party, plugin); + } + + @Override + public void onClick(Player player, ClickType clickType) + { + new PlayerSuggestPlayerMenu(getPlugin(), player, getParty()).openInventory(); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyInvitesMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyInvitesMenu.java new file mode 100644 index 000000000..2ba29aad6 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyInvitesMenu.java @@ -0,0 +1,190 @@ +package mineplex.core.party.ui.menus; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.party.InviteData; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.Menu; +import mineplex.core.party.ui.button.IconButton; +import mineplex.core.party.ui.button.tools.invite.*; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * The menu showing all pending invites for a player + */ +public class PartyInvitesMenu extends Menu +{ + + private final IconButton NO_INVITES = new IconButton(new ItemBuilder(Material.STAINED_GLASS_PANE) + .setData(DyeColor.RED.getWoolData()) + .setTitle(C.cRedB + "No Invites") + .build(), null); + + private final int SLOTS_PER_PAGE = 27; + private final int STARTING_SLOT = 18; + private final int BACK_BUTTON_SLOT = 0; + private final int DENY_ALL_BUTTON_SLOW = 4; + private final int FILTER_BUTTON_SLOT = 8; + private final int NEXT_PAGE_SLOT = 53; + private int _currentPage; + private int _pagesNeeded; + + private Map> _pagesOfData; + private List _data; + + private String _filterBy; + + public PartyInvitesMenu(PartyManager plugin) + { + super("Invites", plugin); + } + + public PartyInvitesMenu(PartyManager plugin, String filterBy) + { + this(plugin); + _filterBy = filterBy; + } + + @Override + protected Button[] setUp(Player player) + { + boolean showFiltered = false; + + _buttons[BACK_BUTTON_SLOT] = new BackButton(_plugin); + + List all = (List) _plugin.getInviteManager().getAllInvites(player); + + if (all == null || all.isEmpty()) + { + for (int i = 10; i < 44; i++) + { + _buttons[i] = NO_INVITES; + } + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, .6f); + return addPanes(_buttons); + } + + _buttons[DENY_ALL_BUTTON_SLOW] = new DenyAllButton(_plugin); + + if (_filterBy == null || _filterBy.isEmpty()) + { + _buttons[FILTER_BUTTON_SLOT] = new FilterButton(_plugin); + } else + { + showFiltered = true; + _buttons[FILTER_BUTTON_SLOT] = new FilterButton(_filterBy, _plugin); + } + + if (showFiltered) + { + all = all.stream().filter(inviteData -> inviteData.getInvitedTo().contains(_filterBy)).collect(Collectors.toList()); + } + + if (showFiltered && all.isEmpty()) + { + for (int i = 10; i < 44; i++) + { + _buttons[i] = new IconButton(new ItemBuilder(Material.STAINED_GLASS_PANE) + .setData(DyeColor.RED.getWoolData()) + .setTitle(C.cRedB + "No Invites Found") + .setLore(" ", C.cGray + "The filter " + F.name(_filterBy) + " had no results.") + .build(), _plugin); + } + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, .6f); + return addPanes(_buttons); + } + + _data = all; + + if (all.size() > SLOTS_PER_PAGE) + { + int pagesNeeded = 0; + int size = all.size(); + while (size > SLOTS_PER_PAGE) + { + pagesNeeded++; + size -= SLOTS_PER_PAGE; + } + _buttons[NEXT_PAGE_SLOT] = new NextPageButton(this, _plugin); + + _pagesNeeded = pagesNeeded; + _pagesOfData = Maps.newHashMap(); + + int page = 0; + + List newData = Lists.newArrayList(); + int total = all.size(); + for (int i = 0; i < pagesNeeded; i++) + { + for (int s = 0; s < total; s++) + { + newData.add(all.remove(i)); + if (i > SLOTS_PER_PAGE) + { + _pagesOfData.put(page++, newData); + newData.clear(); + total -= SLOTS_PER_PAGE; + break; + } + } + } + //Add pages + } else + { + for (int i = 0; i < all.size(); i++) + { + String to = all.get(i).getInvitedTo(); + _buttons[STARTING_SLOT + i] = new InviteButton(to, _plugin); + } + } + + + return addPanes(_buttons); + } + + public void setButton(int slot, Button button) + { + getButtons()[slot] = button; + } + + public List getDataForPage(int page) + { + return _pagesOfData.get(page); + } + + public int getStartingSlot() + { + return STARTING_SLOT; + } + + public int getCurrentPage() + { + return _currentPage; + } + + public void setCurrentPage(int currentPage) + { + _currentPage = currentPage; + } + + public List getData() + { + return _data; + } + + public int getPagesNeeded() + { + return _pagesNeeded; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyMainMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyMainMenu.java new file mode 100644 index 000000000..619e2f1f7 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyMainMenu.java @@ -0,0 +1,36 @@ +package mineplex.core.party.ui.menus; + +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.Menu; +import mineplex.core.party.ui.button.tools.main.InvitePlayerButton; +import mineplex.core.party.ui.button.tools.main.ViewInvitesButton; +import org.bukkit.entity.Player; + +/** + * The main GUI for parties. + */ +public class PartyMainMenu extends Menu +{ + + private final int INV_SIZE = 9; + + private final int INVITE_PLAYER_BUTTON_SLOT = 3; + private final int VIEW_INVITES_BUTTON_SLOT = 5; + + public PartyMainMenu(PartyManager plugin) + { + super("Mineplex Parties", plugin); + } + + @Override + protected Button[] setUp(Player player) + { + Button[] buttons = new Button[INV_SIZE]; + + buttons[INVITE_PLAYER_BUTTON_SLOT] = new InvitePlayerButton(_plugin); + buttons[VIEW_INVITES_BUTTON_SLOT] = new ViewInvitesButton(_plugin); + + return buttons; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyOwnerMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyOwnerMenu.java new file mode 100644 index 000000000..2bdf85157 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyOwnerMenu.java @@ -0,0 +1,84 @@ +package mineplex.core.party.ui.menus; + +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.Menu; +import mineplex.core.party.ui.button.PartyMemberIcon; +import mineplex.core.party.ui.button.tools.LeavePartyButton; +import mineplex.core.party.ui.button.tools.owner.AddPlayerButton; +import mineplex.core.party.ui.button.tools.owner.DisbandPartyButton; +import mineplex.core.party.ui.button.tools.owner.KickPlayerButton; +import mineplex.core.party.ui.button.tools.owner.SelectServerButton; +import mineplex.core.party.ui.button.tools.owner.TransferOwnerButton; +import org.bukkit.entity.Player; + +/** + * The display menu for managing parties by the owner + */ +public class PartyOwnerMenu extends Menu +{ + + private final int STARTING_SLOT = 20; + private final int CUT_OFF_SLOT = 25; + private final int SKIP_TO_SLOT = 29; + private final int ADD_PLAYER_BUTTON_SLOT = 1; + private final int KICK_PLAYER_BUTTON_SLOT = 4; + private final int TRANSFER_OWNER_BUTTON_SLOT = 7; + private final int SELECT_SERVER_BUTTON_SLOT = 46; + private final int LEAVE_PARTY_BUTTON_SLOT = 49; + private final int DISBAND_PARTY_BUTTON_SLOW = 52; + + private Party _party; + + public PartyOwnerMenu(Party party, PartyManager plugin) + { + super("Manage Party", plugin); + _party = party; + //We want this disabled by default + if(_party.isOwnerKickMode()) + { + _party.setOwnerKickMode(false); + } + } + + @Override + protected Button[] setUp(Player player) + { + //Tools + _buttons[ADD_PLAYER_BUTTON_SLOT] = new AddPlayerButton(_plugin, _party); + //Kick player + _buttons[KICK_PLAYER_BUTTON_SLOT] = new KickPlayerButton(_party); + //Transfer ownership + _buttons[TRANSFER_OWNER_BUTTON_SLOT] = new TransferOwnerButton(_party, _plugin); + //Go to server + _buttons[SELECT_SERVER_BUTTON_SLOT] = new SelectServerButton(_party); + //Leave party + _buttons[LEAVE_PARTY_BUTTON_SLOT] = new LeavePartyButton(_plugin); + //Disband + _buttons[DISBAND_PARTY_BUTTON_SLOW] = new DisbandPartyButton(_plugin); + + int slot = STARTING_SLOT; + //Players + for (int i = 0; i < _party.getMembers().size(); i++) + { + if (slot == CUT_OFF_SLOT) + { + slot = SKIP_TO_SLOT; + } + String member = _party.getMembers().get(i); + _buttons[slot++] = new PartyMemberIcon(member, _party, member.equalsIgnoreCase(_party.getOwner())); + } + + if(_party.getSize() == 5) + { + for(int i = 29; i < 34; i++) + { + _buttons[i] = PURCHASE_MORE_SLOTS; + } + } + + + return addPanes(_buttons); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyViewMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyViewMenu.java new file mode 100644 index 000000000..80df07b28 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyViewMenu.java @@ -0,0 +1,54 @@ +package mineplex.core.party.ui.menus; + +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.Menu; +import mineplex.core.party.ui.button.PartyMemberIcon; +import mineplex.core.party.ui.button.tools.LeavePartyButton; +import mineplex.core.party.ui.button.tools.view.SuggestPlayerButton; +import org.bukkit.entity.Player; + +/** + * The menu a player see's when he is a member, and not an owner, of a party. + */ +public class PartyViewMenu extends Menu +{ + + private final int STARTING_SLOT = 20; + private final int CUT_OFF_SLOT = 25; + private final int SKIP_TO_SLOT = 29; + private final int LEAVE_PARTY_BUTTON_SLOT = 3; + private final int SUGGEST_PLAYER_BUTTON_SLOT = 5; + + private Party _party; + + public PartyViewMenu(Party party, PartyManager plugin) + { + super(party.getName() + "'s Party", plugin); + _party = party; + } + + @Override + protected Button[] setUp(Player player) + { + //Tools + _buttons[LEAVE_PARTY_BUTTON_SLOT] = new LeavePartyButton(_plugin); + //Suggest Player + _buttons[SUGGEST_PLAYER_BUTTON_SLOT] = new SuggestPlayerButton(_party, _plugin); + + int slot = STARTING_SLOT; + //Players + for (int i = 0; i < _party.getMembers().size(); i++) + { + if (slot == CUT_OFF_SLOT) + { + slot = SKIP_TO_SLOT; + } + String member = _party.getMembers().get(i); + _buttons[slot++] = new PartyMemberIcon(member, _party, member.equalsIgnoreCase(_party.getOwner())); + } + + return addPanes(_buttons); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/InviteFilterMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/InviteFilterMenu.java new file mode 100644 index 000000000..24de3bc87 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/InviteFilterMenu.java @@ -0,0 +1,30 @@ +package mineplex.core.party.ui.menus.input; + +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.menus.PartyInvitesMenu; +import mineplex.core.anvilMenu.PlayerInputActionMenu; +import org.bukkit.entity.Player; + +/** + * The anvil menu for filtering the players invite menu + */ +public class InviteFilterMenu extends PlayerInputActionMenu +{ + + public InviteFilterMenu(PartyManager partyManager, Player player, Party party) + { + super(partyManager, player, party); + } + + @Override + public void inputReceived(String name) + { + _player.closeInventory(); + if(name.equalsIgnoreCase("Clear Filter") || name.equalsIgnoreCase(" ")) + { + name = null; + } + new PartyInvitesMenu((PartyManager) _plugin, name).open(_player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PartyInvitePlayerMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PartyInvitePlayerMenu.java new file mode 100644 index 000000000..4e30ebc07 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PartyInvitePlayerMenu.java @@ -0,0 +1,42 @@ +package mineplex.core.party.ui.menus.input; + +import mineplex.core.anvilMenu.player.PlayerNameMenu; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import mineplex.core.party.ui.menus.PartyOwnerMenu; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +/** + * The anvil menu for inviting a player to a party + */ +public class PartyInvitePlayerMenu extends PlayerNameMenu +{ + + private PartyManager _partyManager; + + public PartyInvitePlayerMenu(PartyManager partyManager, Player player, Party party) + { + super(partyManager, partyManager.getClientManager(), player, party); + _partyManager = partyManager; + } + + @Override + public void onSuccess(String name) + { + _partyManager.getMethodManager().invite(_player, name); + _player.playSound(_player.getLocation(), Sound.NOTE_PLING, 1, 1.6f); + _player.closeInventory(); + if (_party == null) + { + return; + } + new PartyOwnerMenu(_party, _partyManager).open(_player); + } + + @Override + public void onFail(String name) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PartyTransferOwnerMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PartyTransferOwnerMenu.java new file mode 100644 index 000000000..8f407393b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PartyTransferOwnerMenu.java @@ -0,0 +1,38 @@ +package mineplex.core.party.ui.menus.input; + +import mineplex.core.anvilMenu.player.PlayerNameMenu; +import mineplex.core.party.Lang; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import org.bukkit.entity.Player; + +/** + * + */ +public class PartyTransferOwnerMenu extends PlayerNameMenu +{ + + private PartyManager _partyManager; + + public PartyTransferOwnerMenu(PartyManager partyManager, Player player, Party party) + { + super(partyManager, partyManager.getClientManager(), player, party); + _partyManager = partyManager; + } + + + @Override + public void onSuccess(String name) + { + _partyManager.getMethodManager().transferOwner(name, _player.getName()); + Lang.TRANSFER_OWNER.send(_party, _player.getName(), name); + _player.closeInventory(); + _player.chat("/party"); + } + + @Override + public void onFail(String name) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PlayerSuggestPlayerMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PlayerSuggestPlayerMenu.java new file mode 100644 index 000000000..d6fb40f38 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/input/PlayerSuggestPlayerMenu.java @@ -0,0 +1,61 @@ +package mineplex.core.party.ui.menus.input; + +import mineplex.core.anvilMenu.player.PlayerNameMenu; +import mineplex.core.common.jsonchat.ChildJsonMessage; +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.HoverEvent; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.party.Lang; +import mineplex.core.party.Party; +import mineplex.core.party.PartyManager; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +/** + * The Anvil Menu for handling suggestions + */ +public class PlayerSuggestPlayerMenu extends PlayerNameMenu +{ + + public PlayerSuggestPlayerMenu(PartyManager partyManager, Player player, Party party) + { + super(partyManager, partyManager.getClientManager(), player, party); + } + + @Override + public void onSuccess(String name) + { + if(_party == null || _party.getOwner() == null) + { + Lang.NO_PARTY.send(_player); + return; + } + + if(_party.contains(name)) + { + Lang.ALREADY_MEMBER.send(_player, name); + return; + } + + Player player = Bukkit.getPlayerExact(_party.getOwner()); + + _party.sendMessage(C.mHead + "Party> " + F.name(_player.getName()) + " has suggested " + F.name(name) + " be invited."); + + ChildJsonMessage message = new ChildJsonMessage("").extra(F.main("Party", "Click ")); + message.add(F.link("Invite " + name)) + .hover(HoverEvent.SHOW_TEXT, C.cGreen + "Clicking this will invite " + C.cYellow + name + C.cGreen + " to the party") + .click(ClickEvent.RUN_COMMAND, "/partyinvite " + name); + message.add(C.mBody + " to invite them"); + message.sendToPlayer(player); + + _player.closeInventory(); + _player.chat("/party"); + } + + @Override + public void onFail(String name) + { + + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/portal/Portal.java b/Plugins/Mineplex.Core/src/mineplex/core/portal/Portal.java index d5a24913f..813744f5d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/portal/Portal.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/portal/Portal.java @@ -93,37 +93,33 @@ public class Portal extends MiniPlugin final boolean override = serverName.equalsIgnoreCase("Lobby"); final Rank playerRank = _clientManager.Get(player).GetRank(); - + + if(event.isCancel() && !event.isDraggedByParty()) + { + return; + } + if (override) { sendPlayer(player, serverName); } + else { - runAsync(new Runnable() - { - public void run() - { - final MinecraftServer server = _repository.getServerStatus(serverName); - - if (server == null) - return; - - Bukkit.getServer().getScheduler().runTask(_plugin, new Runnable() + runAsync(() -> { + final MinecraftServer server = _repository.getServerStatus(serverName); + + if (server == null) + return; + + Bukkit.getServer().getScheduler().runTask(_plugin, () -> { + if (server.getPlayerCount() < server.getMaxPlayerCount() || playerRank.has(Rank.ULTRA)) { - public void run() - { - if (server.getPlayerCount() < server.getMaxPlayerCount() || playerRank.has(Rank.ULTRA)) - { - sendPlayer(player, serverName); - } - else - UtilPlayer.message( - player, - F.main(getName(), C.cGold + serverName + C.cRed + " is full!")); - } - }); - } + sendPlayer(player, serverName); + } + else + UtilPlayer.message(player, F.main(getName(), C.cGold + serverName + C.cRed + " is full!")); + }); }); } } @@ -140,20 +136,10 @@ public class Portal extends MiniPlugin if (callback == null) return; - Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), new Runnable() - { - public void run() - { - final boolean serverExists = ServerManager.getServerRepository(_region).serverExists(serverName); - - Bukkit.getScheduler().runTask(getPlugin(), new Runnable() - { - public void run() - { - callback.run(serverExists); - } - }); - } + Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> { + final boolean serverExists = ServerManager.getServerRepository(_region).serverExists(serverName); + + Bukkit.getScheduler().runTask(getPlugin(), () -> callback.run(serverExists)); }); } @@ -205,16 +191,8 @@ public class Portal extends MiniPlugin player.sendPluginMessage(getPlugin(), "BungeeCord", b.toByteArray()); _connectingPlayers.add(player.getName()); - getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() - { - public void run() - { - _connectingPlayers.remove(player.getName()); - } - }, 20L); + getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> _connectingPlayers.remove(player.getName()), 20L); - UtilPlayer.message( - player, - F.main(getName(), "You have been sent from " + C.cGold + _serverName + C.cGray + " to " + C.cGold + serverName)); + UtilPlayer.message(player, F.main(getName(), "You have been sent from " + C.cGold + _serverName + C.cGray + " to " + C.cGold + serverName)); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/portal/ServerTransferEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/portal/ServerTransferEvent.java index 94262b8d7..e2dc4c667 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/portal/ServerTransferEvent.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/portal/ServerTransferEvent.java @@ -11,6 +11,7 @@ public class ServerTransferEvent extends Event private Player _player; private String _server; private boolean _draggedByParty; + private boolean _cancel; public ServerTransferEvent(Player player, String server, boolean draggedByParty) { @@ -24,6 +25,11 @@ public class ServerTransferEvent extends Event return _draggedByParty; } + public void setDraggedByParty(boolean draggedByParty) + { + _draggedByParty = draggedByParty; + } + public HandlerList getHandlers() { return _handlers; @@ -44,4 +50,13 @@ public class ServerTransferEvent extends Event return _server; } + public boolean isCancel() + { + return _cancel; + } + + public void setCancel(boolean cancel) + { + _cancel = cancel; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 0277ef72b..da590e9b6 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -587,9 +587,9 @@ public class HubManager extends MiniClientPlugin if (rank != Rank.ALL) rankStr = rank.getTag(true, true) + " "; //Party Chat - if (event.getMessage().charAt(0) == '@') + if (event.getMessage().charAt(0) == '#') { - Party party = _partyManager.GetParty(player); + Party party = _partyManager.getParty(player); if (party != null) { event.getRecipients().clear(); @@ -597,7 +597,7 @@ public class HubManager extends MiniClientPlugin event.setMessage(event.getMessage().substring(1, event.getMessage().length())); event.setFormat(levelStr + C.cDPurple + C.Bold + "Party " + C.cWhite + C.Bold + playerName + " " + C.cPurple + "%2$s"); - for (String name : party.GetPlayers()) + for (String name : party.getMembers()) { Player other = UtilPlayer.searchExact(name); @@ -626,10 +626,6 @@ public class HubManager extends MiniClientPlugin 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()) { if (_tutorialManager.InTutorial(other)) @@ -638,9 +634,7 @@ public class HubManager extends MiniClientPlugin continue; } - // event.setMessage(event.getMessage()); - // event.setFormat(levelStr + rankStr + C.cYellow + playerName + " " + C.cWhite + "%2$s"); - if(!event.isCancelled()) + if (!event.isCancelled()) other.spigot().sendMessage(component); } event.setCancelled(true); @@ -715,9 +709,6 @@ public class HubManager extends MiniClientPlugin for (Player player : UtilServer.getPlayers()) { - //Dont Waste Time - if (_partyManager.GetParty(player) != null) - continue; //Return to Main Scoreboard if (!player.getScoreboard().equals(_scoreboards.get(player))) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java index f0a5122cb..7a44aee11 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java @@ -1,10 +1,6 @@ package mineplex.hub.queue.ui; -import java.util.ArrayList; -import java.util.List; - import mineplex.core.account.CoreClientManager; -import mineplex.core.common.util.UtilPlayer; import mineplex.core.donation.DonationManager; import mineplex.core.party.Party; import mineplex.core.shop.item.IButton; @@ -12,12 +8,15 @@ import mineplex.core.shop.item.ShopItem; import mineplex.core.shop.page.ShopPageBase; import mineplex.hub.queue.PlayerMatchStatus; import mineplex.hub.queue.QueueManager; - +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import java.util.List; +import java.util.stream.Collectors; + public class QueuePage extends ShopPageBase { private boolean _closeOnNextUpdate; @@ -131,32 +130,17 @@ public class QueuePage extends ShopPageBase private void queuePlayer(int gameType, Player player) { - Party party = getPlugin().getPartyManager().GetParty(player); - - if (party != null) - { - if (player.getName().equals(party.GetLeader())) - { - List players = new ArrayList(); - - for (String name : party.GetPlayers()) - { - Player partyPlayer = UtilPlayer.searchExact(name); - - if (partyPlayer == null) - continue; - - players.add(partyPlayer); - } - - getPlugin().queuePlayer(gameType, players.toArray(new Player[]{})); - } - } - else + Party party = getPlugin().getPartyManager().getParty(player); + if(party == null) { getPlugin().queuePlayer(gameType, player); + return; + } + if(party.getOwner().equalsIgnoreCase(player.getName())) + { + List players = party.getMembers().stream().map(Bukkit::getPlayerExact).collect(Collectors.toList()); + getPlugin().queuePlayer(gameType, players.toArray(new Player[players.size()])); } - buildPage(); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java index 33b2c6bbd..7f1b163fc 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java @@ -1,7 +1,5 @@ package mineplex.hub.queue.ui; -import java.util.Iterator; - import mineplex.core.account.CoreClientManager; import mineplex.core.common.util.C; import mineplex.core.common.util.F; @@ -11,12 +9,13 @@ import mineplex.core.shop.page.ShopPageBase; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.queue.QueueManager; - import org.bukkit.ChatColor; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import java.util.Iterator; + public class QueueShop extends ShopBase { public QueueShop(QueueManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager, String name) @@ -33,9 +32,9 @@ public class QueueShop extends ShopBase @Override protected boolean canOpenShop(Player player) { - Party party = getPlugin().getPartyManager().GetParty(player); + Party party = getPlugin().getPartyManager().getParty(player); - if (party != null && !player.getName().equalsIgnoreCase(party.GetLeader())) + if (party != null && !player.getName().equalsIgnoreCase(party.getOwner())) { player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, .6f); player.sendMessage(F.main("Party", "Only Party Leaders can join games.")); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java index 4a885c432..32ba26c92 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java @@ -13,6 +13,8 @@ import java.util.Set; import mineplex.core.boosters.BoosterManager; import mineplex.core.brawl.fountain.BrawlShopProvider; +import mineplex.core.party.Lang; +import mineplex.core.party.event.PartySelectServerEvent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -352,7 +354,13 @@ public class ServerManager extends MiniDbClientPlugin implement { return _serverInfoMap.get(serverName); } - + + @EventHandler + public void onClickCompassPartyIcon(PartySelectServerEvent event) + { + _quickShop.attemptShopOpen(event.getPlayer()); + } + @EventHandler public void updatePages(UpdateEvent event) { @@ -512,17 +520,23 @@ public class ServerManager extends MiniDbClientPlugin implement return _partyManager; } - public void selectServer(org.bukkit.entity.Player player, ServerInfo serverInfo) + public void selectServer(Player player, ServerInfo serverInfo) { - Party party = _partyManager.GetParty(player); - - if (party == null || player.getName().equals(party.GetLeader())) + Party party = _partyManager.getParty(player); + if(party != null) { - player.leaveVehicle(); - player.eject(); - - _portal.sendPlayerToServer(player, serverInfo.Name); + if(!party.getOwner().equalsIgnoreCase(player.getName())) + { + Lang.NOT_OWNER_SERVER.send(player); + return; + } + _partyManager.getJoinManager().requestServerJoin(serverInfo.Name, party); + return; } + player.leaveVehicle(); + player.eject(); + + _portal.sendPlayerToServer(player, serverInfo.Name); } /** @@ -578,7 +592,7 @@ public class ServerManager extends MiniDbClientPlugin implement } /** - * @param serverType - the type of server that should be fetched + * @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) @@ -735,32 +749,9 @@ public class ServerManager extends MiniDbClientPlugin implement 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++; - } + + if (!_clientManager.Get(player).GetRank().has(Rank.ULTRA) && !_donationManager.Get(player.getName()).OwnsUnknownPackage(serverType + " ULTRA")) + slots++; return slots; } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcShop.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcShop.java index 100a4689d..491f3ff0e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcShop.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcShop.java @@ -1,8 +1,5 @@ package mineplex.hub.server.ui; -import org.bukkit.Sound; -import org.bukkit.entity.Player; - import mineplex.core.account.CoreClientManager; import mineplex.core.common.util.C; import mineplex.core.common.util.F; @@ -12,6 +9,8 @@ import mineplex.core.shop.ShopBase; import mineplex.core.shop.page.ShopPageBase; import mineplex.hub.server.ServerManager; import mineplex.serverdata.data.ServerGroup; +import org.bukkit.Sound; +import org.bukkit.entity.Player; public class ServerNpcShop extends ShopBase { @@ -41,9 +40,9 @@ public class ServerNpcShop extends ShopBase @Override protected boolean canOpenShop(Player player) { - Party party = getPlugin().getPartyManager().GetParty(player); - - if (party != null && !player.getName().equalsIgnoreCase(party.GetLeader())) + Party party = getPlugin().getPartyManager().getParty(player); + + if (party != null && !player.getName().equalsIgnoreCase(party.getOwner())) { player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, .6f); player.sendMessage(F.main("Party", "Only Party Leaders can join games.")); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClanMoveServerShop.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClanMoveServerShop.java index e85528ee8..84f99ce39 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClanMoveServerShop.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClanMoveServerShop.java @@ -1,8 +1,5 @@ package mineplex.hub.server.ui.clans; -import org.bukkit.Sound; -import org.bukkit.entity.Player; - import mineplex.core.account.CoreClientManager; import mineplex.core.common.util.F; import mineplex.core.donation.DonationManager; @@ -12,6 +9,8 @@ import mineplex.core.shop.page.ShopPageBase; import mineplex.game.clans.core.repository.ClanRepository; import mineplex.game.clans.core.repository.tokens.SimpleClanToken; import mineplex.hub.server.ServerManager; +import org.bukkit.Sound; +import org.bukkit.entity.Player; public class ClanMoveServerShop extends ShopBase { @@ -37,7 +36,7 @@ public class ClanMoveServerShop extends ShopBase @Override protected boolean canOpenShop(Player player) { - Party party = getPlugin().getPartyManager().GetParty(player); + Party party = getPlugin().getPartyManager().getParty(player); if (party != null) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClansServerShop.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClansServerShop.java index f5590b095..6d6926a16 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClansServerShop.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/clans/ClansServerShop.java @@ -1,8 +1,5 @@ package mineplex.hub.server.ui.clans; -import org.bukkit.Sound; -import org.bukkit.entity.Player; - import mineplex.core.account.CoreClientManager; import mineplex.core.common.util.F; import mineplex.core.donation.DonationManager; @@ -11,6 +8,8 @@ import mineplex.core.shop.ShopBase; import mineplex.core.shop.page.ShopPageBase; import mineplex.game.clans.core.repository.ClanRepository; import mineplex.hub.server.ServerManager; +import org.bukkit.Sound; +import org.bukkit.entity.Player; public class ClansServerShop extends ShopBase { @@ -32,7 +31,7 @@ public class ClansServerShop extends ShopBase @Override protected boolean canOpenShop(Player player) { - Party party = getPlugin().getPartyManager().GetParty(player); + Party party = getPlugin().getPartyManager().getParty(player); if (party != null) { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java index 76a31e27e..bcd04629c 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java @@ -9,6 +9,7 @@ import mineplex.core.elo.EloTeam; import mineplex.core.itemstack.ItemBuilder; import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.PacketInfo; +import mineplex.core.party.Party; import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; @@ -1145,8 +1146,7 @@ public abstract class Game implements Listener { return team.GetSize() < PlayersPerTeam; } - return Manager.IsTeamBalance() ? team.GetSize() < Math.max(1, UtilServer.getPlayers().length / GetTeamList().size()) - : true; + return !Manager.IsTeamBalance() || team.GetSize() < Math.max(1, UtilServer.getPlayers().length / GetTeamList().size()); } @EventHandler diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java index 2bb9542fb..6c63497ef 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java @@ -1,19 +1,5 @@ package nautilus.game.arcade.managers.chat; -import java.text.DecimalFormat; -import java.util.AbstractMap; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; - -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.AsyncPlayerChatEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; - import mineplex.core.account.CoreClient; import mineplex.core.common.Rank; import mineplex.core.common.jsonchat.JsonMessage; @@ -25,8 +11,22 @@ import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.Game.GameState; import nautilus.game.arcade.game.GameTeam; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.jooq.tools.json.JSONObject; +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; + +import static mineplex.database.routines.Test.playerName; +import static sun.audio.AudioPlayer.player; + public class GameChatManager implements Listener { @@ -122,31 +122,31 @@ public class GameChatManager implements Listener rankStr = rank.getTag(true, true) + " " + C.Reset; } - if (event.getMessage().charAt(0) == '@') + //Party Chat + if (event.getMessage().charAt(0) == '#') { - //Party Chat - Party party = _manager.getPartyManager().GetParty(sender); - + Party party = _manager.getPartyManager().getParty(sender); if (party != null) { event.getRecipients().clear(); - rankStr = C.cDPurpleB + "Party " + C.Reset; - event.setMessage(event.getMessage().substring(1, event.getMessage().length())); - event.setFormat(levelStr + rankStr + C.cWhiteB + senderName + " " + C.cPurple + "%2$s"); + event.setFormat(levelStr + C.cDPurple + C.Bold + "Party " + C.cWhite + C.Bold + playerName + " " + C.cPurple + "%2$s"); - format = event.getFormat().split(rankStr)[0]; - name = C.cWhiteB + sender.getName() + C.Reset; - message = event.getFormat().split(sender.getName())[1].replace("%2$s", "") + _manager.GetChat().getFilteredMessage(sender, event.getMessage()); - - if(safeSend(sender, format, rankStr, rank, name, message, party.GetPlayersOnline())) + for (String member : party.getMembers()) { - event.setCancelled(true); - } + Player other = UtilPlayer.searchExact(member); - return; + if (other != null) + event.getRecipients().add(other); + } } + else + { + UtilPlayer.message(sender, F.main("Party", "You are not in a Party.")); + event.setCancelled(true); + } + return; } event.setFormat(levelStr + rankStr + senderName + " " + C.cWhite + "%2$s");