package com.nyancraft.reportrts.command.sub; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.nyancraft.reportrts.RTSFunctions; import com.nyancraft.reportrts.RTSPermissions; import com.nyancraft.reportrts.ReportRTS; import com.nyancraft.reportrts.data.Comment; import com.nyancraft.reportrts.data.Ticket; import com.nyancraft.reportrts.persistence.DataProvider; import com.nyancraft.reportrts.util.BungeeCord; import com.nyancraft.reportrts.util.Message; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.json.simple.JSONObject; import java.lang.reflect.InvocationTargetException; import java.text.SimpleDateFormat; import java.util.*; public class ReadTicket { private static ReportRTS plugin = ReportRTS.getPlugin(); private static DataProvider data = plugin.getDataProvider(); private static SimpleDateFormat sdf = new SimpleDateFormat("MMM.dd kk:mm z"); private static String substring; /** * Initial handling of the Read sub-command. * @param sender player that sent the command * @param args arguments * @return true if command handled correctly */ public static boolean handleCommand(CommandSender sender, String[] args) { // Not enough arguments to be anything but "/ticket read". if(args.length < 2) return viewPage(sender, 1); // We need to figure out what form of action the user has specified. switch(args[1].toUpperCase()) { case "P": case "PAGE": if(args.length < 3) return viewPage(sender, 1); return viewPage(sender, RTSFunctions.isNumber(args[2]) ? Integer.parseInt(args[2]) : 1); case "H": case "HELD": if(args.length < 3) return viewHeld(sender, 1); return viewHeld(sender, RTSFunctions.isNumber(args[2]) ? Integer.parseInt(args[2]) : 1); case "C": case "CLOSED": if(args.length < 3) return viewClosed(sender, 1); return viewClosed(sender, RTSFunctions.isNumber(args[2]) ? Integer.parseInt(args[2]) : 1); case "S": case "SERVER": if(args.length < 3) return viewServer(sender, BungeeCord.getServerName(), 1); if(args.length == 4) return viewServer(sender, args[3], 1); if(args.length >= 5) return viewServer(sender, args[3], RTSFunctions.isNumber(args[4]) ? Integer.parseInt(args[4]) : 1); break; case "SELF": return viewSelf(sender, args); default: // Defaults to this if not found. In this case we need to figure out what the command is trying to do. if(RTSFunctions.isNumber(args[1])) return viewId(sender, Integer.parseInt(args[1])); sender.sendMessage(Message.error("No valid action specified.")); break; } return true; } /** * View specified ticket. * @param sender commandsender * @param id ticket number * @return true if command handled correctly */ private static boolean viewId(CommandSender sender, int id) { boolean restrict = false; if(!RTSPermissions.canReadAll(sender)) { if(!RTSPermissions.canReadOwnClosed(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read")); return true; } restrict = true; } Ticket ticket = plugin.tickets.get(id); // Ticket does not exist in the tickets map and must be retrieved from the database. if(ticket == null) { ticket = data.getTicket(id); if(ticket == null) { sender.sendMessage(Message.ticketNotExists(id)); return true; } } // If the user does not have access to readAll then ensure that the ticket is owned by that player. if(restrict && !ticket.getUUID().equals(sender instanceof Player ? ((Player) sender).getUniqueId() : data.getConsole().getUuid())) { sender.sendMessage(Message.errorTicketOwner()); return true; } // Sets the colour of the player's name depending on whether they are online or not. ChatColor online = (RTSFunctions.isUserOnline(ticket.getUUID())) ? ChatColor.GREEN : ChatColor.RED; String date = sdf.format(new Date(ticket.getTimestamp() * 1000)); ChatColor statusColor = null; String status = null; if(ticket.getStatus() == 0) { status = "Open"; statusColor = ChatColor.YELLOW; } if(ticket.getStatus() == 1) { status = "Claimed"; statusColor = ChatColor.RED; } if(ticket.getStatus() == 2) { status = "On Hold"; statusColor = ChatColor.LIGHT_PURPLE; } if(ticket.getStatus() == 3) { status = "Closed"; statusColor = ChatColor.GREEN; } // Compile a response for the user. sender.sendMessage(ChatColor.AQUA + "--------- " + "Ticket #" + ticket.getId() + " - " + statusColor + status + ChatColor.AQUA + " ---------"); sender.sendMessage(ChatColor.YELLOW + "Opened by" + online + " " + ticket.getName() + ChatColor.YELLOW + " at " + ChatColor.GREEN + date + ChatColor.YELLOW + " at X:" + ChatColor.GREEN + ticket.getX() + ChatColor.YELLOW + ", Y:" + ChatColor.GREEN + ticket.getY() + ChatColor.YELLOW + ", Z:" + ChatColor.GREEN + ticket.getZ()); sender.sendMessage(ChatColor.GRAY + ticket.getMessage()); if(ticket.getStatus() == 1) { long Millis = (System.currentTimeMillis() - (ticket.getStaffTime()) * 1000); sender.sendMessage(ChatColor.LIGHT_PURPLE + String.format("Claimed for: %d hours, %d minutes, %d seconds", Millis/(1000*60*60), (Millis%(1000*60*60))/(1000*60), ((Millis%(1000*60*60))%(1000*60))/1000) + " by " + ticket.getStaffName()); } if(ticket.getComments() != null && !ticket.getComments().isEmpty()) { sender.sendMessage(ChatColor.YELLOW + "Comments: "); Iterator it = ticket.getComments().iterator(); while(it.hasNext()) { Comment comment = (Comment) it.next(); sender.sendMessage(ChatColor.GOLD + comment.getName() + ChatColor.YELLOW + ": " + ChatColor.GREEN + comment.getComment()); } } return true; } /** * View the specified page. Defaults to 1. * @param sender player that sent the command * @param page page number * @return true if command handled correctly */ private static boolean viewPage(CommandSender sender, int page) { if(!RTSPermissions.canReadAll(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read")); return true; } if(page < 0) page = 1; int a = page * plugin.ticketsPerPage; // Compile a response for the user. sender.sendMessage(ChatColor.AQUA + "--------- " + plugin.tickets.size() + " Tickets -" + ChatColor.YELLOW + " Open " + ChatColor.AQUA + "---------"); if(plugin.tickets.isEmpty()) sender.sendMessage(Message.ticketReadNone()); List<Ticket> tmpList = new ArrayList<>(plugin.tickets.values()); // Sets the start location of the "cursor". for(int i = (page * plugin.ticketsPerPage) - plugin.ticketsPerPage; i < a && i < plugin.tickets.size(); i++) { if(i < 0) i = 1; Ticket ticket = tmpList.get(i); if(plugin.hideWhenOffline && !RTSFunctions.isUserOnline(ticket.getUUID())){ a++; continue; } substring = RTSFunctions.shortenMessage(ticket.getMessage()); substring = (ticket.getStatus() == 1) ? ChatColor.LIGHT_PURPLE + "Claimed by " + ticket.getStaffName() : ChatColor.GRAY + substring; String bungeeServer = (ticket.getServer().equals(BungeeCord.getServer()) ? "" : "[" + ChatColor.GREEN + ticket.getServer() + ChatColor.RESET + "] "); if(plugin.fancify && (sender instanceof Player) && ticket.getMessage().length() >= 20) { PacketContainer chat = new PacketContainer(PacketType.Play.Server.CHAT); chat.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\":\"" + bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + RTSFunctions.getTimeAgo(ticket.getTimestamp()) + " by " + ((RTSFunctions.isUserOnline(ticket.getUUID())) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + "\", \"extra\":[{\"text\":\"" + JSONObject.escape(substring) + "\",\"color\":\"" + (ticket.getStatus() == 1 ? "light_purple" :"gray") + "\",\"hoverEvent\":" + "{\"action\":\"show_text\",\"value\":\"" + JSONObject.escape(RTSFunctions.separateText(ticket.getMessage(), 6)) + "\"}}]}")); try { ProtocolLibrary.getProtocolManager().sendServerPacket((Player) sender, chat); } catch (InvocationTargetException e) { e.printStackTrace(); return false; } } else { sender.sendMessage(bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + RTSFunctions.getTimeAgo(ticket.getTimestamp()) + " by " + ((RTSFunctions.isUserOnline(ticket.getUUID())) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + substring); } } return true; } /** * View tickets put on hold. * @param sender player that sent the command * @param page page number * @return true if command handled correctly */ private static boolean viewHeld(CommandSender sender, int page) { if(!RTSPermissions.canReadAll(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read")); return true; } // Set cursor start position. int i = (page * plugin.ticketsPerPage) - plugin.ticketsPerPage; LinkedHashMap<Integer, Ticket> tickets = data.getTickets(2, i, plugin.ticketsPerPage); if(tickets == null) { sender.sendMessage(Message.error("Can't read held tickets, see console for errors.")); return true; } sender.sendMessage(ChatColor.AQUA + "--------- " + tickets.size() + " Tickets -" + ChatColor.YELLOW + " Held " + ChatColor.AQUA + "---------"); if(tickets.isEmpty()) sender.sendMessage(Message.ticketReadNoneHeld()); for(Map.Entry<Integer, Ticket> entry : tickets.entrySet()) { Ticket ticket = entry.getValue(); substring = RTSFunctions.shortenMessage(ticket.getMessage()); ChatColor online = (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED); String bungeeServer = (ticket.getServer().equals(BungeeCord.getServer()) ? "" : "[" + ChatColor.GREEN + ticket.getServer() + ChatColor.RESET + "] "); if(plugin.fancify && (sender instanceof Player) && ticket.getMessage().length() >= 20) { PacketContainer chat = new PacketContainer(PacketType.Play.Server.CHAT); chat.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\":\"" + bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + "\", \"extra\":[{\"text\":\"" + JSONObject.escape(substring) + "\",\"color\":\"gray\",\"hoverEvent\":" + "{\"action\":\"show_text\",\"value\":\"" + JSONObject.escape(RTSFunctions.separateText(ticket.getMessage(), 6)) + "\"}}]}")); try { ProtocolLibrary.getProtocolManager().sendServerPacket((Player) sender, chat); } catch (InvocationTargetException e) { e.printStackTrace(); return false; } } else { sender.sendMessage(bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + online + ticket.getName() + ChatColor.GOLD + " - " + ChatColor.GRAY + substring); } } return true; } /** * View tickets that have been resolved. * @param sender player that sent the command * @param page page number * @return true if command handled correctly */ private static boolean viewClosed(CommandSender sender, int page) { if(!RTSPermissions.canReadAll(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read")); return true; } // Set cursor position. int i = (page * plugin.ticketsPerPage) - plugin.ticketsPerPage; LinkedHashMap<Integer, Ticket> tickets = data.getTickets(3, i, plugin.ticketsPerPage); if(tickets == null) { sender.sendMessage(Message.error("Can't read closed tickets, see console for errors.")); return true; } sender.sendMessage(ChatColor.AQUA + "--------- " + tickets.size() + " Tickets -" + ChatColor.YELLOW + " Closed " + ChatColor.AQUA + "--------- "); if(tickets.isEmpty()) sender.sendMessage(Message.ticketReadNoneClosed()); for(Map.Entry<Integer, Ticket> entry : tickets.entrySet()) { Ticket ticket = entry.getValue(); substring = RTSFunctions.shortenMessage(ticket.getMessage()); ChatColor online = (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED); String bungeeServer = (ticket.getServer().equals(BungeeCord.getServer()) ? "" : "[" + ChatColor.GREEN + ticket.getServer() + ChatColor.RESET + "] "); if(plugin.fancify && (sender instanceof Player) && ticket.getMessage().length() >= 20) { PacketContainer chat = new PacketContainer(PacketType.Play.Server.CHAT); chat.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\":\"" + bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + "\", \"extra\":[{\"text\":\"" + JSONObject.escape(substring) + "\",\"color\":\"gray\",\"hoverEvent\":" + "{\"action\":\"show_text\",\"value\":\"" + JSONObject.escape(RTSFunctions.separateText(ticket.getMessage(), 6)) + "\"}}]}")); try { ProtocolLibrary.getProtocolManager().sendServerPacket((Player) sender, chat); } catch (InvocationTargetException e) { e.printStackTrace(); return false; } } else { sender.sendMessage(bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + online + ticket.getName() + ChatColor.GOLD + " - " + ChatColor.GRAY + substring); } } return true; } /** * View open tickets on a specific server. * @param sender player that sent the command * @param server name of target server * @param page page number * @return true if command handled correctly. */ private static boolean viewServer(CommandSender sender, String server, int page) { if(!RTSPermissions.canReadAll(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read")); return true; } if(page < 0) page = 0; // Set cursor position. int a = (page * plugin.ticketsPerPage) - plugin.ticketsPerPage; // Compile a response for the user. sender.sendMessage(ChatColor.AQUA + "--------- " + plugin.tickets.size() + " Tickets From Server " + server + " -" + ChatColor.YELLOW + " Open " + ChatColor.AQUA + "---------"); if(plugin.tickets.isEmpty()) sender.sendMessage(Message.ticketReadNone()); List<Ticket> tmpList = new ArrayList<>(plugin.tickets.values()); for(int i = (page * plugin.ticketsPerPage) - plugin.ticketsPerPage; i < a && i < plugin.tickets.size(); i++){ Ticket ticket = tmpList.get(i); if(plugin.hideWhenOffline && !RTSFunctions.isUserOnline(ticket.getUUID()) || !ticket.getServer().equals(server)){ a++; continue; } substring = RTSFunctions.shortenMessage(ticket.getMessage()); substring = (ticket.getStatus() == 1) ? ChatColor.LIGHT_PURPLE + "Claimed by " + ticket.getStaffName() : ChatColor.GRAY + substring; if(plugin.fancify && (sender instanceof Player) && ticket.getMessage().length() >= 20) { PacketContainer chat = new PacketContainer(PacketType.Play.Server.CHAT); chat.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\":\"" + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + ((RTSFunctions.isUserOnline(ticket.getUUID())) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + "\", \"extra\":[{\"text\":\"" +JSONObject.escape(substring) + "\",\"color\":\"gray\",\"hoverEvent\":" + "{\"action\":\"show_text\",\"value\":\"" + JSONObject.escape(RTSFunctions.separateText(ticket.getMessage(), 6)) + "\"}}]}")); try { ProtocolLibrary.getProtocolManager().sendServerPacket((Player) sender, chat); } catch (InvocationTargetException e) { e.printStackTrace(); return false; } } else { sender.sendMessage(ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + substring); } } return true; } /** * View tickets opened by yourself. * @param sender player that sent the command * @return true if command handled correctly */ private static boolean viewSelf(CommandSender sender, String[] args) { if(!RTSPermissions.canReadOwn(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read.self")); return true; } // Read own closed tickets if specified. if(args.length > 2 && args[2].equalsIgnoreCase("closed")) return viewSelfClosed(sender, args); int openRequests = 0; for(Map.Entry<Integer, Ticket> entry : plugin.tickets.entrySet()) if(entry.getValue().getName().equals(sender.getName())) openRequests++; int i = 0; sender.sendMessage(ChatColor.AQUA + "--------- " + ChatColor.YELLOW + " You have " + openRequests + " unresolved tickets " + ChatColor.AQUA + "----------"); if(openRequests == 0) sender.sendMessage(Message.ticketReadNoneSelf()); for(Map.Entry<Integer, Ticket> entry : plugin.tickets.entrySet()) { Ticket ticket = entry.getValue(); if (!ticket.getName().equals(sender.getName())) continue; i++; if (i > 5) break; String substring = RTSFunctions.shortenMessage(ticket.getMessage()); substring = (ticket.getStatus() == 1) ? ChatColor.LIGHT_PURPLE + "Claimed by " + ticket.getStaffName() : ChatColor.GRAY + substring; String bungeeServer = (ticket.getServer().equals(BungeeCord.getServer()) ? "" : "[" + ChatColor.GREEN + ticket.getServer() + ChatColor.RESET + "] "); if(plugin.fancify && (sender instanceof Player) && ticket.getMessage().length() >= 20) { PacketContainer chat = new PacketContainer(PacketType.Play.Server.CHAT); chat.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\":\"" + bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + ((RTSFunctions.isUserOnline(ticket.getUUID())) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + "\", \"extra\":[{\"text\":\"" + JSONObject.escape(substring) + "\",\"color\":\"gray\",\"hoverEvent\":" + "{\"action\":\"show_text\",\"value\":\"" + JSONObject.escape(RTSFunctions.separateText(ticket.getMessage(), 6)) + "\"}}]}")); try { ProtocolLibrary.getProtocolManager().sendServerPacket((Player) sender, chat); } catch (InvocationTargetException e) { e.printStackTrace(); return false; } } else { sender.sendMessage(ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + substring); } } return true; } /** * View tickets you have made that have been resolved. * @param sender Player that sent the command * @param args Arguments * @return boolean */ private static boolean viewSelfClosed(CommandSender sender, String[] args) { if(!RTSPermissions.canReadOwnClosed(sender)) { sender.sendMessage(Message.errorPermission("reportrts.command.read.self.closed")); return true; } int page = 1; if(args.length > 3 && RTSFunctions.isNumber(args[3])) page = Integer.parseInt(args[3]); // Set cursor position. int i = (page * plugin.ticketsPerPage) - plugin.ticketsPerPage; LinkedHashMap<Integer, Ticket> tickets = data.getOpenedBy(sender instanceof Player ? ((Player) sender).getUniqueId() : plugin.getDataProvider().getConsole().getUuid(), i, plugin.ticketsPerPage); if(tickets == null) { sender.sendMessage(Message.error("Can't read closed tickets, see console for errors.")); return true; } sender.sendMessage(ChatColor.AQUA + "--------- " + ChatColor.YELLOW + "You have " + tickets.size() + " resolved tickets " + ChatColor.AQUA + "--------- "); if(tickets.isEmpty()) sender.sendMessage(Message.ticketReadNoneClosed()); for(Map.Entry<Integer, Ticket> entry : tickets.entrySet()) { Ticket ticket = entry.getValue(); substring = RTSFunctions.shortenMessage(ticket.getMessage()); ChatColor online = (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED); String bungeeServer = (ticket.getServer().equals(BungeeCord.getServer()) ? "" : "[" + ChatColor.GREEN + ticket.getServer() + ChatColor.RESET + "] "); if(plugin.fancify && (sender instanceof Player) && ticket.getMessage().length() >= 20) { PacketContainer chat = new PacketContainer(PacketType.Play.Server.CHAT); chat.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\":\"" + bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + (RTSFunctions.isUserOnline(ticket.getUUID()) ? ChatColor.GREEN : ChatColor.RED) + ticket.getName() + ChatColor.GOLD + " - " + "\", \"extra\":[{\"text\":\"" + JSONObject.escape(substring) + "\",\"color\":\"gray\",\"hoverEvent\":" + "{\"action\":\"show_text\",\"value\":\"" + JSONObject.escape(RTSFunctions.separateText(ticket.getMessage(), 6)) + "\"}}]}")); try { ProtocolLibrary.getProtocolManager().sendServerPacket((Player) sender, chat); } catch (InvocationTargetException e) { e.printStackTrace(); return false; } } else { sender.sendMessage(bungeeServer + ChatColor.GOLD + "#" + ticket.getId() + " " + sdf.format(new Date(ticket.getTimestamp() * 1000)) + " by " + online + ticket.getName() + ChatColor.GOLD + " - " + ChatColor.GRAY + substring); } } return true; } }