Finished staff chat.

Cleaned up tickets.
Added ticket types and location.
This commit is contained in:
Brianna O'Keefe 2019-03-08 20:12:34 -05:00
parent 07abbaf42b
commit 353ca0ca6b
15 changed files with 245 additions and 52 deletions

12
.gitignore vendored
View File

@ -250,3 +250,15 @@ target/classes/com/songoda/ultimatemoderation/utils/MySQLDatabase\.class
target/classes/com/songoda/ultimatemoderation/utils/version/NMSUtil\.class
target/classes/com/songoda/ultimatemoderation/gui/GUIPunishments\$PunishmentHolder\.class
\.idea/\.name
\.idea/encodings\.xml
target/classes/com/songoda/ultimatemoderation/command/commands/CommandStaffChat\.class
target/classes/com/songoda/ultimatemoderation/staffchat/StaffChannel\.class
target/classes/com/songoda/ultimatemoderation/staffchat/StaffChatManager\.class
target/classes/com/songoda/ultimatemoderation/gui/GUITicketType\.class

View File

@ -177,8 +177,10 @@ public class UltimateModeration extends JavaPlugin {
int id = row.get("id").asInt();
Ticket ticket = new Ticket(
UUID.fromString(row.get("player").asString()),
row.get("subject").asString());
row.get("subject").asString(),
row.get("type").asString());
ticket.setTicketId(id);
ticket.setLocation(Methods.unserializeLocation(row.get("location").asString()));
ticket.setStatus(TicketStatus.valueOf(row.get("status").asString()));
ticketManager.addTicket(ticket, id);
}

View File

@ -28,10 +28,10 @@ public class CommandStaffChat extends AbstractCommand {
for (StaffChannel channel : instance.getStaffChatManager().getChats().values()) {
if (!channel.listMembers().contains(player.getUniqueId())) continue;
channel.removeMember(player);
player.sendMessage("You left " + channel.getChannelName() + " successfully.");
player.sendMessage(instance.getReferences().getPrefix() + instance.getLocale().getMessage("event.staffchat.leave", channel.getChannelName()));
return ReturnType.SUCCESS;
}
player.sendMessage("You are not in any channels.");
player.sendMessage(instance.getReferences().getPrefix() + instance.getLocale().getMessage("event.staffchat.nochannels"));
return ReturnType.FAILURE;
}

View File

@ -17,7 +17,6 @@ public class CommandUltimateModeration extends AbstractCommand {
@Override
protected ReturnType runCommand(UltimateModeration instance, CommandSender sender, String... args) {
new GUIPlayers(instance, (Player) sender);
return ReturnType.SUCCESS;
}

View File

@ -71,6 +71,9 @@ public class GUITicket extends AbstractGUI {
createButton(8, Material.OAK_DOOR, plugin.getLocale().getMessage("gui.general.back"));
if (player.hasPermission("um.ticket.clicktotele") && ticket.getLocation() != null)
createButton(7, Material.REDSTONE, plugin.getLocale().getMessage("gui.ticket.clicktotele"));
createButton(6, Material.REDSTONE, plugin.getLocale().getMessage("gui.ticket.respond"));
for (int i = 0; i < 9; i++)
@ -113,15 +116,20 @@ public class GUITicket extends AbstractGUI {
@Override
protected void registerClickables() {
if (player.hasPermission("um.ticket.openclose")) {
registerClickable(8, ((player1, inventory1, cursor, slot, type) ->
new GUITicketManager(plugin, toModerate, player)));
registerClickable(8, ((player1, inventory1, cursor, slot, type) ->
new GUITicketManager(plugin, toModerate, player)));
if (player.hasPermission("um.ticket.clicktotele") && ticket.getLocation() != null) {
registerClickable(7, ((player1, inventory1, cursor, slot, type) ->
player.teleport(ticket.getLocation())));
}
registerClickable(5, ((player1, inventory1, cursor, slot, type) -> {
ticket.setStatus(ticket.getStatus() == TicketStatus.OPEN ? TicketStatus.CLOSED : TicketStatus.OPEN);
constructGUI();
}));
if (player.hasPermission("um.ticket.openclose")) {
registerClickable(5, ((player1, inventory1, cursor, slot, type) -> {
ticket.setStatus(ticket.getStatus() == TicketStatus.OPEN ? TicketStatus.CLOSED : TicketStatus.OPEN);
constructGUI();
}));
}
registerClickable(6, ((player1, inventory1, cursor, slot, type) -> {
player.sendMessage(plugin.getLocale().getMessage("gui.ticket.what"));

View File

@ -111,6 +111,7 @@ public class GUITicketManager extends AbstractGUI {
if (toModerate != null)
lore.add(plugin.getLocale().getMessage("gui.tickets.player", Bukkit.getOfflinePlayer(ticket.getVictim()).getName()));
lore.add(plugin.getLocale().getMessage("gui.ticket.type", ticket.getType()));
lore.add(plugin.getLocale().getMessage("gui.ticket.createdon", format.format(new Date(ticket.getCreationDate()))));
lore.add(plugin.getLocale().getMessage("gui.tickets.click"));
@ -124,7 +125,7 @@ public class GUITicketManager extends AbstractGUI {
@Override
protected void registerClickables() {
if (player.hasPermission("um.ticket")) {
if (player.hasPermission("um.moderate")) {
registerClickable(8, ((player1, inventory1, cursor, slot, type) -> {
if (toModerate == null)
new GUIPlayers(plugin, player);
@ -148,19 +149,8 @@ public class GUITicketManager extends AbstractGUI {
public static void createNew(Player player, OfflinePlayer toModerate) {
UltimateModeration plugin = UltimateModeration.getInstance();
AbstractAnvilGUI gui = new AbstractAnvilGUI(player, event -> {
Ticket ticket = new Ticket(toModerate, event.getName());
player.sendMessage(plugin.getLocale().getMessage("gui.tickets.what"));
AbstractChatConfirm abstractChatConfirm = new AbstractChatConfirm(player, event2 -> {
plugin.getTicketManager().addTicket(ticket);
ticket.addResponse(new TicketResponse(player, event2.getMessage(), System.currentTimeMillis()));
});
abstractChatConfirm.setOnClose(() ->
new GUITicket(plugin, ticket, toModerate, player));
});
AbstractAnvilGUI gui = new AbstractAnvilGUI(player, event ->
new GUITicketType(plugin, toModerate, player, event.getName()));
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();

View File

@ -0,0 +1,71 @@
package com.songoda.ultimatemoderation.gui;
import com.songoda.ultimatemoderation.UltimateModeration;
import com.songoda.ultimatemoderation.tickets.Ticket;
import com.songoda.ultimatemoderation.tickets.TicketResponse;
import com.songoda.ultimatemoderation.tickets.TicketStatus;
import com.songoda.ultimatemoderation.utils.AbstractChatConfirm;
import com.songoda.ultimatemoderation.utils.SettingsManager;
import com.songoda.ultimatemoderation.utils.gui.AbstractGUI;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
public class GUITicketType extends AbstractGUI {
private final UltimateModeration plugin;
private final OfflinePlayer toModerate;
private final String subject;
public GUITicketType(UltimateModeration plugin, OfflinePlayer toModerate, Player player, String subject) {
super(player);
this.plugin = plugin;
this.toModerate = toModerate;
this.subject = subject;
init(plugin.getLocale().getMessage("gui.ticket.picktype"), 27);
}
@Override
protected void constructGUI() {
inventory.clear();
resetClickables();
registerClickables();
List<String> types = SettingsManager.Setting.TICKET_TYPES.getStringList();
for (int i = 0; i < types.size(); i ++) {
createButton(i, Material.PAPER, types.get(i));
final int fi = i;
registerClickable(i, (player1, inventory1, cursor, slot, type) -> {
Ticket ticket = new Ticket(toModerate, subject, types.get(fi));
player.sendMessage(plugin.getLocale().getMessage("gui.tickets.what"));
AbstractChatConfirm abstractChatConfirm = new AbstractChatConfirm(player, event2 -> {
plugin.getTicketManager().addTicket(ticket);
if (player == toModerate)
ticket.setLocation(player.getLocation());
ticket.addResponse(new TicketResponse(player, event2.getMessage(), System.currentTimeMillis()));
});
abstractChatConfirm.setOnClose(() ->
new GUITicket(plugin, ticket, toModerate, player));
});
}
}
@Override
protected void registerClickables() {
}
@Override
protected void registerOnCloses() {
}
}

View File

@ -32,17 +32,10 @@ public class ChatListener implements Listener {
public void onChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
for (Map.Entry<String, StaffChannel> entry : instance.getStaffChatManager().getChats().entrySet()) {
String channel = entry.getKey();
StaffChannel members = entry.getValue();
if (!members.listMembers().contains(player.getUniqueId())) continue;
for (StaffChannel channel : instance.getStaffChatManager().getChats().values()) {
if (!channel.listMembers().contains(player.getUniqueId())) continue;
event.setCancelled(true);
for (UUID uuid : members.listMembers()) {
Player p = Bukkit.getPlayer(uuid);
if (p == null) continue;
p.sendMessage(Methods.formatText(channel + " " + player.getDisplayName() + "&" + members.getChatChar() + ": " + event.getMessage()));
}
channel.processMessage(event.getMessage(), player);
}
if (!isChatToggled && !player.hasPermission("um.togglechat.bypass")) {

View File

@ -2,18 +2,22 @@ package com.songoda.ultimatemoderation.staffchat;
import com.songoda.ultimatemoderation.UltimateModeration;
import com.songoda.ultimatemoderation.utils.Methods;
import com.songoda.ultimatemoderation.utils.SettingsManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class StaffChannel {
private final String channelName;
private char chatChar = 'b';
private char chatChar = SettingsManager.Setting.STAFFCHAT_COLOR_CODE.getChar();
private final List<UUID> members = new ArrayList<>();
private final List<String> chatLog = new ArrayList<>();
public StaffChannel(String channelName) {
this.channelName = channelName;
@ -30,19 +34,27 @@ public class StaffChannel {
}
});
members.add(player.getUniqueId());
for (UUID uuid : members) {
Player p = Bukkit.getPlayer(uuid);
if (p == null) continue;
p.sendMessage(Methods.formatText(channelName + " " + player.getDisplayName() + "&" + chatChar + " has just entered the channel."));
if (chatLog.size() > 5) {
chatLog.stream().skip(chatLog.size() - 3).forEach(message -> player.sendMessage(Methods.formatText(message)));
}
messageAll(UltimateModeration.getInstance().getLocale().getMessage("event.staffchat.format.join", chatChar, channelName, player.getDisplayName()));
}
public void removeMember(Player player) {
members.remove(player.getUniqueId());
messageAll(UltimateModeration.getInstance().getLocale().getMessage("event.staffchat.format.leave", chatChar, channelName, player.getDisplayName()));
}
public void processMessage(String message, Player player) {
messageAll(UltimateModeration.getInstance().getLocale().getMessage("event.staffchat.format", chatChar, channelName, player.getDisplayName(), chatChar, message));
}
private void messageAll(String message) {
chatLog.add(message);
for (UUID uuid : members) {
Player p = Bukkit.getPlayer(uuid);
if (p == null) continue;
p.sendMessage(Methods.formatText(channelName + " " + player.getDisplayName() + "&" + chatChar + " has just left the channel."));
Player player = Bukkit.getPlayer(uuid);
if (player == null) continue;
player.sendMessage(Methods.formatText(message));
}
}

View File

@ -9,6 +9,7 @@ import com.songoda.ultimatemoderation.tickets.Ticket;
import com.songoda.ultimatemoderation.tickets.TicketResponse;
import com.songoda.ultimatemoderation.tickets.TicketStatus;
import com.songoda.ultimatemoderation.utils.ConfigWrapper;
import com.songoda.ultimatemoderation.utils.Methods;
import java.util.List;
import java.util.UUID;
@ -70,6 +71,8 @@ public abstract class Storage {
prepareSaveItem("tickets", new StorageItem("id", ticket.getTicketId()),
new StorageItem("player", ticket.getVictim().toString()),
new StorageItem("subject", ticket.getSubject()),
new StorageItem("type", ticket.getType()),
new StorageItem("location", Methods.serializeLocation(ticket.getLocation())),
new StorageItem("status", ticket.getStatus().toString()));
for (TicketResponse ticketResponse : ticket.getResponses()) {

View File

@ -1,5 +1,6 @@
package com.songoda.ultimatemoderation.tickets;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import java.util.ArrayList;
@ -11,30 +12,37 @@ public class Ticket {
private int ticketId;
private TicketStatus status = TicketStatus.OPEN;
private Location location = null;
private String type;
private final List<TicketResponse> tickets = new ArrayList<>();
private final UUID victim;
private final String subject;
public Ticket(OfflinePlayer victim, String subject) {
public Ticket(OfflinePlayer victim, String subject, String type) {
this.victim = victim.getUniqueId();
this.subject = subject;
this.type = type;
}
public Ticket(UUID victim, String subject) {
public Ticket(UUID victim, String subject, String type) {
this.victim = victim;
this.subject = subject;
this.type = type;
}
public Ticket(OfflinePlayer victim, String subject, TicketResponse response) {
public Ticket(OfflinePlayer victim, String subject, String type, TicketResponse response) {
this.victim = victim.getUniqueId();
this.subject = subject;
this.type = type;
this.tickets.add(response);
}
public Ticket(UUID victim, String subject, TicketResponse response) {
public Ticket(UUID victim, String subject, String type, TicketResponse response) {
this.victim = victim;
this.subject = subject;
this.type = type;
this.tickets.add(response);
}
@ -80,4 +88,16 @@ public class Ticket {
public void setStatus(TicketStatus status) {
this.status = status;
}
public String getType() {
return type;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
}

View File

@ -1,15 +1,21 @@
package com.songoda.ultimatemoderation.utils;
import com.songoda.ultimatemoderation.UltimateModeration;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class Methods {
private static Map<String, Location> serializeCache = new HashMap<>();
public static ItemStack getGlass() {
UltimateModeration instance = UltimateModeration.getInstance();
return Methods.getGlass(instance.getConfig().getBoolean("Interfaces.Replace Glass Type 1 With Rainbow Glass"), instance.getConfig().getInt("Interfaces.Glass Type 1"));
@ -89,4 +95,67 @@ public class Methods {
}
return 0;
}
public static String convertToInvisibleString(String s) {
if (s == null || s.equals(""))
return "";
StringBuilder hidden = new StringBuilder();
for (char c : s.toCharArray()) hidden.append(ChatColor.COLOR_CHAR + "").append(c);
return hidden.toString();
}
/**
* Serializes the location of the block specified.
*
* @param b The block whose location is to be saved.
* @return The serialized data.
*/
public static String serializeLocation(Block b) {
if (b == null)
return "";
return serializeLocation(b.getLocation());
}
/**
* Serializes the location specified.
*
* @param location The location that is to be saved.
* @return The serialized data.
*/
public static String serializeLocation(Location location) {
if (location == null)
return "";
String w = location.getWorld().getName();
double x = location.getX();
double y = location.getY();
double z = location.getZ();
String str = w + ":" + x + ":" + y + ":" + z;
str = str.replace(".0", "").replace("/", "");
return str;
}
/**
* Deserializes a location from the string.
*
* @param str The string to parse.
* @return The location that was serialized in the string.
*/
public static Location unserializeLocation(String str) {
if (str == null || str.equals(""))
return null;
if (serializeCache.containsKey(str)) {
return serializeCache.get(str).clone();
}
String cacheKey = str;
str = str.replace("y:", ":").replace("z:", ":").replace("w:", "").replace("x:", ":").replace("/", ".");
List<String> args = Arrays.asList(str.split("\\s*:\\s*"));
World world = Bukkit.getWorld(args.get(0));
double x = Double.parseDouble(args.get(1)), y = Double.parseDouble(args.get(2)), z = Double.parseDouble(args.get(3));
Location location = new Location(world, x, y, z, 0, 0);
serializeCache.put(cacheKey, location.clone());
return location;
}
}

View File

@ -24,7 +24,7 @@ public class SettingsManager implements Listener {
private static final Pattern SETTINGS_PATTERN = Pattern.compile("(.{1,28}(?:\\s|$))|(.{0,28})", Pattern.DOTALL);
private final UltimateModeration instance;
private String pluginName = "EpicHoppers";
private String pluginName = "UltimateModeration";
private Map<Player, String> cat = new HashMap<>();
private Map<Player, String> current = new HashMap<>();
@ -177,6 +177,9 @@ public class SettingsManager implements Listener {
AUTOSAVE("Main.Auto Save Interval In Seconds", 15),
STAFFCHAT_COLOR_CODE("Main.Staff Chat Color Code", 'b'),
TICKET_TYPES("Main.Ticket Types", Arrays.asList("Grief", "Player Report", "Bug Report", "Suggestion", "Other")),
GLASS_TYPE_1("Interfaces.Glass Type 1", 7),
GLASS_TYPE_2("Interfaces.Glass Type 2", 11),
GLASS_TYPE_3("Interfaces.Glass Type 3", 3),
@ -216,5 +219,7 @@ public class SettingsManager implements Listener {
return UltimateModeration.getInstance().getConfig().getString(setting);
}
public char getChar() { return UltimateModeration.getInstance().getConfig().getString(setting).charAt(0); }
}
}

View File

@ -67,12 +67,12 @@ public class AbstractAnvilGUI {
AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name);
handler.onAnvilClick(clickEvent);
if (clickEvent.getWillClose()) {
event.getWhoClicked().closeInventory();
}
handler.onAnvilClick(clickEvent);
if (clickEvent.getWillDestroy()) {
destroy();
}

View File

@ -55,6 +55,12 @@ event.kick.message = "&7You have been kicked"
event.warning.success = "&7You have warned &6%player%"
event.warning.message = "&7You have been warned"
event.staffchat.leave = "&7You left &6%channel% &7successfully."
event.staffchat.nochannels = "&cYou are not in any channels."
event.staffchat.format.join = "&%color%[%channel%] %player% has just joined the channel."
event.staffchat.format.leave = "&%color%[%channel%] %player% has just left the channel."
event.staffchat.format = "&%color%[%channel%] %player%&%color%: %message%"
#GUI Messages
gui.general.previous = "&6Previous Page"
@ -148,6 +154,9 @@ gui.tickets.what = "&6What would you like to say in your first ticket post?"
gui.tickets.subject = "Ticket Subject"
gui.ticket.title = "&8Tickets > %id%";
gui.ticket.type = "&7Type &6%type%&7."
gui.ticket.picktype = "&8Pick a ticket type.";
gui.ticket.clicktotele = "&6Teleport to ticket location.";
gui.ticket.createdon = "&7Created on &6%time%&7."
gui.ticket.respond = "&6Respond"
gui.ticket.status = "&7Status &6%status%&7."