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..860ad7504 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/InviteData.java @@ -0,0 +1,51 @@ +package mineplex.core.party; + +/** + * Serializable invite data + */ +public class InviteData +{ + + private String _invitedTo; + private String _invitedBy; + private long _timeStamp; + private long _expires; + + public InviteData(String invitedBy, String invitedTo, long timeStamp) + { + _invitedBy = invitedBy; + _invitedTo = invitedTo; + _timeStamp = timeStamp; + _expires = timeStamp + 60000; + } + + public long getTimeRemaining() + { + return _expires - System.currentTimeMillis(); + } + + public boolean hasExpired() + { + return System.currentTimeMillis() >= _expires; + } + + public String getInvitedTo() + { + return _invitedTo; + } + + public String getInvitedBy() + { + return _invitedBy; + } + + public long getTimeStamp() + { + return _timeStamp; + } + + public long getExpires() + { + return _expires; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java b/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java index e4d4104c0..cd222f1ae 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/PartyManager.java @@ -1,16 +1,69 @@ package mineplex.core.party; +import com.google.common.collect.Maps; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.Callback; +import mineplex.core.party.redis.locate.LocateType; +import mineplex.core.party.redis.locate.PartyRedisLocate; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; +import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import java.util.Map; +import java.util.UUID; + public class PartyManager extends MiniPlugin { + private Portal _portal; + private CoreClientManager _clientManager; + private PreferencesManager _preferencesManager; + + private String _serverName; + + private Map _players = Maps.newHashMap(); + private Map _parties = Maps.newHashMap(); + private Map _pendingInvites = Maps.newHashMap(); + public PartyManager(JavaPlugin plugin, Portal portal, CoreClientManager clientManager, PreferencesManager preferenceManager) { super("Parties", plugin); + _portal = portal; + _clientManager = clientManager; + _preferencesManager = preferenceManager; + _serverName = _plugin.getConfig().getString("serverstatus.name"); + } + + public void locatePlayer(String player, Callback callback, LocateType reason) + { + runAsync(() -> { + //locate player + //Find the player and callback with the results + runSync(() -> { + callback.run("SomeServer (TBD when Connor Replies)"); + }); + }); + } + + public Portal getPortal() + { + return _portal; + } + + public CoreClientManager getClientManager() + { + return _clientManager; + } + + public PreferencesManager getPreferencesManager() + { + return _preferencesManager; + } + + public void summon(Player player, String target) + { + new PartyRedisLocate(_serverName, player.getName(), target, LocateType.TRANSFER); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java index d487a2bf2..553891dc0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/command/PartyCommand.java @@ -16,7 +16,7 @@ public class PartyCommand extends CommandBase private final String[] HELP = { C.cDGreenB + C.Strike + "================================", F.main("Party", "/party help - Shows this help screen."), - F.main("Party", "/party - Brings up the Party UI."), + F.main("Party", "/party - Brings up the Party GUI."), F.main("Party", "/party invite - Invite a player to your party." + C.cRed + " Must be the owner."), F.main("Party", "/party accept - Accept an invite to a player's party."), F.main("Party", "/party deny - Deny an invite to a player's party."), @@ -34,50 +34,84 @@ public class PartyCommand extends CommandBase @Override public void Execute(Player caller, String[] args) { - if(args.length == 0) + if (args.length == 0) { //Show UI return; } String argument = args[0]; - if(argument.equalsIgnoreCase("help")) + if (argument.equalsIgnoreCase("help")) { //Show this menu caller.sendMessage(HELP); return; } - if(args.length == 1) + if (args.length == 1) { - if(argument.equalsIgnoreCase("leave")) + if (argument.equalsIgnoreCase("leave")) { + handleLeave(caller); return; } - if(argument.equalsIgnoreCase("disband")) + if (argument.equalsIgnoreCase("disband")) { + handleDisband(caller); return; } return; } - if(args.length == 2) + if (args.length == 2) { String target = args[1]; - if(argument.equalsIgnoreCase("invite")) + if (argument.equalsIgnoreCase("invite")) { + handleInvite(caller, target); return; } - if(argument.equalsIgnoreCase("accept")) + if (argument.equalsIgnoreCase("accept")) { + handleInviteResponse(caller, target, true); return; } - if(argument.equalsIgnoreCase("deny")) + if (argument.equalsIgnoreCase("deny")) { + handleInviteResponse(caller, target, false); return; } - if(argument.equalsIgnoreCase("remove") || argument.equalsIgnoreCase("kick")) + if (argument.equalsIgnoreCase("remove") || argument.equalsIgnoreCase("kick")) { - return; + handleForceRemove(caller, target); } } } + + private void handleInvite(Player caller, String target) + { + + } + + private void handleInviteResponse(Player caller, String target, boolean accept) + { + if(accept) + { + return; + } + + } + + private void handleForceRemove(Player caller, String target) + { + + } + + private void handleLeave(Player caller) + { + + } + + private void handleDisband(Player caller) + { + + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyDataHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyDataHandler.java index a0d4804a4..e1c3bd2fb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyDataHandler.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/PartyDataHandler.java @@ -24,4 +24,14 @@ public class PartyDataHandler implements CommandCallback { } + + public String getCurrentServer() + { + return _currentServer; + } + + public PartyManager getPlugin() + { + return _plugin; + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/LocateType.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/LocateType.java new file mode 100644 index 000000000..0032c8180 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/LocateType.java @@ -0,0 +1,15 @@ +package mineplex.core.party.redis.locate; + +/** + * Simplifies the location callback method + */ +public enum LocateType +{ + + LORE, + INVITE_INIT, + INVITE_RESPONSE, + KICK, + TRANSFER, + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocate.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocate.java new file mode 100644 index 000000000..beef6d43e --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocate.java @@ -0,0 +1,47 @@ +package mineplex.core.party.redis.locate; + +import mineplex.serverdata.commands.ServerCommand; + +import java.util.UUID; + +public class PartyRedisLocate extends ServerCommand +{ + private String _sender; + private String _sendingServer; + private String _target; + private UUID _uuid = UUID.randomUUID(); + private LocateType _locateType; + + public PartyRedisLocate(String sendingServer, String sender, String target, LocateType locateType) + { + _sender = sender; + _target = target; + _sendingServer = sendingServer; + _locateType = locateType; + } + + public String getSender() + { + return _sender; + } + + public String getServer() + { + return _sendingServer; + } + + public String getTarget() + { + return _target; + } + + public UUID getUUID() + { + return _uuid; + } + + public LocateType getLocateType() + { + return _locateType; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocateCallback.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocateCallback.java new file mode 100644 index 000000000..973180ed8 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocateCallback.java @@ -0,0 +1,56 @@ +package mineplex.core.party.redis.locate; + +import mineplex.serverdata.commands.ServerCommand; + +import java.util.UUID; + +public class PartyRedisLocateCallback extends ServerCommand +{ + private String _locatedPlayer; + private String _server; + private String _receivingPlayer; + private UUID _uuid; + private LocateType _locateType; + private String _response; + + public PartyRedisLocateCallback(PartyRedisLocate command, String server, String targetName, LocateType locateType, String response) + { + _uuid = command.getUUID(); + _receivingPlayer = command.getSender(); + _locatedPlayer = targetName; + _server = server; + _locateType = locateType; + _response = response; + setTargetServers(command.getServer()); + } + + public String getLocatedPlayer() + { + return _locatedPlayer; + } + + public String getServer() + { + return _server; + } + + public String getReceivingPlayer() + { + return _receivingPlayer; + } + + public UUID getUUID() + { + return _uuid; + } + + public LocateType getLocateType() + { + return _locateType; + } + + public String getResponse() + { + return _response; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocateHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocateHandler.java new file mode 100644 index 000000000..edbf4b060 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/redis/locate/PartyRedisLocateHandler.java @@ -0,0 +1,116 @@ +package mineplex.core.party.redis.locate; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.party.PartyManager; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.ServerCommand; +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; + +public class PartyRedisLocateHandler implements CommandCallback +{ + private PartyManager _plugin; + private String _serverName; + + public PartyRedisLocateHandler(PartyManager plugin) + { + _plugin = plugin; + _serverName = _plugin.getPlugin().getConfig().getString("serverstatus.name"); + } + + @Override + public void run(ServerCommand command) + { + if (command instanceof PartyRedisLocate) + { + PartyRedisLocate locate = (PartyRedisLocate) command; + + Player target = Bukkit.getPlayerExact(locate.getTarget()); + + if (target == null) + { + return; + } + handleLocateRequest(locate, target); + return; + } + if (command instanceof PartyRedisLocateCallback) + { + handleLocatedPlayer((PartyRedisLocateCallback) command); + } + } + + public void handleLocateRequest(PartyRedisLocate locate, Player player) + { + LocateType locateType = locate.getLocateType(); + switch (locateType) + { + case INVITE_INIT: + //A requested invite + player.sendMessage(F.main("Party", C.cYellow + locate.getServer() + C.cGray + " has invited you to their party")); + sendAcceptOrDeny(player, locate.getSender()); + break; + case INVITE_RESPONSE: + break; + case KICK: + break; + case LORE: + break; + case TRANSFER: + break; + } + } + + public void handleLocatedPlayer(PartyRedisLocateCallback command) + { + LocateType locateType = command.getLocateType(); + switch (locateType) + { + case INVITE_INIT: + break; + case INVITE_RESPONSE: + break; + case KICK: + break; + case LORE: + break; + case TRANSFER: + break; + } + } + + public void sendAcceptOrDeny(Player player, String arg) + { + TextComponent textComponent = new TextComponent(F.main("Party", "Click one: ")); + + TextComponent accept = new TextComponent("ACCEPT"); + accept.setColor(ChatColor.GREEN); + accept.setBold(true); + accept.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/party accept " + arg)); + accept.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{ + new TextComponent("Click to run /party accept " + arg) + })); + + textComponent.addExtra(accept); + textComponent.addExtra(" "); + + TextComponent deny = new TextComponent("DENY"); + deny.setColor(ChatColor.RED); + deny.setBold(true); + deny.setClickEvent(new ClickEvent(Action.RUN_COMMAND, "/party deny " + arg)); + deny.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{ + new TextComponent("Click to run /party deny " + arg) + })); + + textComponent.addExtra(deny); + + player.spigot().sendMessage(textComponent); + } + +} 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..f4e8eb954 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Button.java @@ -0,0 +1,44 @@ +package mineplex.core.party.ui; + +import mineplex.core.party.PartyManager; +import org.bukkit.entity.Player; +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); + + 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..35504e7e5 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/Menu.java @@ -0,0 +1,191 @@ +package mineplex.core.party.ui; + +import mineplex.core.party.ui.button.IconButton; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; +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[] EMPTY = new Button[45]; + protected static Map MENUS = new HashMap<>(); + private String _name; + protected Button[] _buttons; + + public Menu(String name) + { + _name = name; + _buttons = EMPTY; + } + + 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); + } + + public String getName() + { + return ChatColor.translateAlternateColorCodes('&', _name); + } + + /** + * 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()); + + 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(); + + 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); + } + } + + 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..8914d2b4f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/MenuListener.java @@ -0,0 +1,45 @@ +package mineplex.core.party.ui; + +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; + } + + button.onClick(player); + } + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/PartyMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/PartyMenu.java deleted file mode 100644 index a9b09004c..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/PartyMenu.java +++ /dev/null @@ -1,8 +0,0 @@ -package mineplex.core.party.ui; - -/** - * The display menu for managing parties - */ -public class PartyMenu -{ -} 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..ccbf61506 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/IconButton.java @@ -0,0 +1,25 @@ +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.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) + { + + } +} 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..132cc2dcd --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/button/PartyMemberIcon.java @@ -0,0 +1,62 @@ +package mineplex.core.party.ui.button; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.party.PartyManager; +import mineplex.core.party.redis.locate.LocateType; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.Menu; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + * The button representing a Party member. + */ +public class PartyMemberIcon extends Button +{ + + private final ItemStack DEFAULT = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, DyeColor.GRAY.getDyeData(), 1, "Locating..."); + + private ItemStack _itemStack; + private String _target; + + public PartyMemberIcon(Player viewer, String player, PartyManager plugin) + { + super(null, plugin); + + _target = player; + + plugin.locatePlayer(player, string -> { + + String[] lore = { + "", + C.cWhite + "Server: " + C.cGreen + string, + "", + C.cGreen + "Click to summon to your server." + }; + + _itemStack = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, + C.cYellow + player, lore); + + Menu.get(viewer.getUniqueId()).update(viewer); + }, LocateType.LORE); + } + + @Override + public void onClick(Player player) + { + getPlugin().summon(player, _target); + } + + @Override + public ItemStack getItemStack() + { + if(_itemStack == null) + { + return DEFAULT; + } + return _itemStack; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyMenu.java b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyMenu.java new file mode 100644 index 000000000..668c6eab2 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/party/ui/menus/PartyMenu.java @@ -0,0 +1,26 @@ +package mineplex.core.party.ui.menus; + +import mineplex.core.party.Party; +import mineplex.core.party.ui.Button; +import mineplex.core.party.ui.Menu; + +/** + * The display menu for managing parties + */ +public class PartyMenu extends Menu +{ + + private Party _party; + + public PartyMenu(Party party) + { + super(party.getOwner() + "'s Party"); + _party = party; + } + + @Override + protected Button[] setUp() + { + return new Button[0]; + } +}