diff --git a/api/src/main/java/com/alttd/chat/config/Config.java b/api/src/main/java/com/alttd/chat/config/Config.java index d6a8f63..a94601a 100755 --- a/api/src/main/java/com/alttd/chat/config/Config.java +++ b/api/src/main/java/com/alttd/chat/config/Config.java @@ -478,4 +478,58 @@ public final class Config { EMOTELIST_FOOTER = getString("commands.emotelist.footer", EMOTELIST_FOOTER); } + private static void nicknameSettings() { + // NickChanged("Messages.NickChanged", "&eYour nickname was changed to %nickname%&e."), + // NickNotChanged("Messages.NickNotChanged", "&eYour nickname request was denied."), + // NickReset("Messages.NickReset", "&eNickname changed back to normal."), + // NickChangedOthers("Messages.NickChangedOthers", "&6%targetplayer%&e's nickname was changed to %nickname%&e."), + // NickTargetNickChange("Messages.NickTargetNickChange", "&eYour nickname was changed to %nickname% &eby %sendernick%&e"), + // NickResetOthers("Messages.NickResetOthers", "&6%player%&6's &enickname was reset back to normal."), + // NickInvalidCharacters("Messages.NickInvalidCharacters", "&eYou can only use letters and numbers in nicknames."), + // NickLengthInvalid("Messages.NickLengthInvalid", "&eNicknames need to be between 3 to 16 characters long."), + // NickPlayerNotOnline("Messages.NickPlayerNotOnline", "&cThat player is not online."), + // NickBlockedColorCodes("Messages.NickBlockedColorCodes", "&eYou have blocked color codes in that nickname."), + // NickUserNotFound("Messages.NickUserNotFound", "&cFailed to set nickname from player, try again from a server this player has been on before."), + // NickAccepted("Messages.NickAccepted", "&aYou accepted %targetPlayer%&a's nickname. They are now called %newNick%&a."), + // NickDenied("Messages.NickDenied", "&aYou denied %targetPlayer%&a's nickname. They are still called %oldNick%&a."), + // NickAlreadyHandled("Messages.NickAlreadyHandled", "&c%targetPlayer%&c's nickname was already accepted or denied."), + // NickNoLuckperms("Messages.NickNoLuckPerms", "&cDue to an issue with LuckPerms /nick try won't work at the moment."), + // NickTooSoon("Messages.NickTooSoon", "&cPlease wait %time%&c until requesting a new nickname"), + // NickRequestReplaced("Messages.NickRequestReplaced", "&aReplaced your previous request %oldRequestedNick%&a with %newRequestedNick%&a."), + // NickNewRequest("Messages.NickNewRequest", "&aNew nickname request by %player%&a!"), + // NickTryout("Messages.NickTryout", "&f%prefix&f %nick%&7: &fHi, this is what my new nickname could look like!"), + // NickRequested("Messages.NickRequested", "&aYour requested to be nicknamed %nick%&a has been received. Staff will accept or deny this request asap!"), + // NickReviewWaiting("Messages.NickReviewWaiting", "&aThere are %amount% nicknames waiting for review!"), + // NickTaken("Messages.NickTaken", "&cSomeone else already has this nickname, or has this name as their username."), + // NickRequestsOnLogin("Messages.NickRequestsOnLogin", "&aCurrent nick requests: %amount%"), + // // Nicknames + // + // if (!config.contains("Nicknames.Lore")) { + // List lore = new ArrayList<>(); + // + // lore.add("&bNew nick: %newNick%"); + // lore.add("&bOld nick: %oldNick%"); + // lore.add("&bLast changed: %lastChanged%"); + // lore.add("&aLeft click to Accept &d| &cRight click to Deny"); + // + // config.set("Nicknames.Lore", lore); + // + // notFoundInConfigMessage("Nicknames.Lore"); + // } + // + // if (!config.contains("Nicknames.WaitTime")) { + // config.set("Nicknames.WaitTime", 86400000); + // notFoundInConfigMessage("Nicknames.WaitTime"); + // } + // + // if (!config.contains("Nicknames.BlockedColorCodes")) { + // config.set("Nicknames.BlockedColorCodes", new String[]{"&k", "&l", "&n", "&m", "&o"}); + // notFoundInConfigMessage("Nicknames.BlockedColorCodes"); + // } + // + // if (!config.contains("Nicknames.AllowedColorCodes")) { + // config.set("Nicknames.AllowedColorCodes", new String[]{"&0", "&1", "&2", "&3", "&4", "&5", "&6", "&7", "&8", "&9", "&a", "&b", "&c", "&d", "&e", "&f", "&r"}); + // notFoundInConfigMessage("Nicknames.AllowedColorCodes"); + // } + } } diff --git a/api/src/main/java/com/alttd/chat/database/Queries.java b/api/src/main/java/com/alttd/chat/database/Queries.java index 76161ac..5d3df66 100755 --- a/api/src/main/java/com/alttd/chat/database/Queries.java +++ b/api/src/main/java/com/alttd/chat/database/Queries.java @@ -1,18 +1,13 @@ package com.alttd.chat.database; import com.alttd.chat.managers.PartyManager; -import com.alttd.chat.objects.ChatUser; -import com.alttd.chat.objects.Mail; -import com.alttd.chat.objects.Party; -import com.alttd.chat.objects.PartyUser; +import com.alttd.chat.objects.*; import com.alttd.chat.objects.channels.Channel; import com.alttd.chat.util.ALogger; import java.sql.*; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.UUID; +import java.util.*; +import java.util.Date; public class Queries { @@ -24,7 +19,8 @@ public class Queries { tables.add("CREATE TABLE IF NOT EXISTS parties (`id` INT NOT NULL AUTO_INCREMENT, `owner_uuid` VARCHAR(36) NOT NULL, `party_name` VARCHAR(36) NOT NULL, `password` VARCHAR(36), PRIMARY KEY (`id`))"); tables.add("CREATE TABLE IF NOT EXISTS chat_users (`uuid` VARCHAR(36) NOT NULL, `party_id` INT NOT NULL, `toggled_channel` VARCHAR(36) NULL DEFAULT NULL, PRIMARY KEY (`uuid`))"); tables.add("CREATE TABLE IF NOT EXISTS mails (`id` INT NOT NULL AUTO_INCREMENT, `uuid` VARCHAR(36) NOT NULL, `sender` VARCHAR(36) NOT NULL, `message` VARCHAR(256) NOT NULL, `sendtime` BIGINT default 0, `readtime` BIGINT default 0, PRIMARY KEY (`id`))"); - + createNicknamesTable(); + createRequestedNicknamesTable(); try { Connection connection = DatabaseConnection.getConnection(); @@ -39,6 +35,51 @@ public class Queries { //----------------------------------------- //Nicknames + private static void createNicknamesTable() { + + try { + String nicknamesTableQuery = "CREATE TABLE IF NOT EXISTS nicknames(" + + "uuid VARCHAR(48) NOT NULL," + + "PRIMARY KEY (uuid))"; + DatabaseConnection.getConnection().prepareStatement(nicknamesTableQuery).executeUpdate(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + + List columns = new ArrayList<>(); + columns.add("ALTER TABLE nicknames ADD nickname VARCHAR(192)"); + columns.add("ALTER TABLE nicknames ADD date_changed BIGINT default 0"); + for (String string : columns) { + try { + DatabaseConnection.getConnection().prepareStatement(string).executeUpdate(); + } catch (Throwable ignored) { + } + } + + } + + private static void createRequestedNicknamesTable() { + + try { + String requestedNicknamesTableQuery = "CREATE TABLE IF NOT EXISTS requested_nicknames(" + + "uuid VARCHAR(48) NOT NULL," + + "PRIMARY KEY (uuid))"; + DatabaseConnection.getConnection().prepareStatement(requestedNicknamesTableQuery).executeUpdate(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + + List columns = new ArrayList<>(); + columns.add("ALTER TABLE requested_nicknames ADD nickname VARCHAR(192)"); + columns.add("ALTER TABLE requested_nicknames ADD date_requested BIGINT default 0"); + for (String string : columns) { + try { + DatabaseConnection.getConnection().prepareStatement(string).executeUpdate(); + } catch (Throwable ignored) { + } + } + + } public static String getNickname(UUID uuid) { // View has been created. @@ -564,4 +605,172 @@ public class Queries { e.printStackTrace(); } } + + // Nicknames + public static void setNicknameInDatabase(final UUID uuid, final String nickName) { + final String sql = "INSERT INTO nicknames (uuid, nickname, date_changed) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE nickname = ?"; + try (final PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(sql)) { + statement.setString(1, uuid.toString()); + statement.setString(2, nickName); + statement.setLong(3, new java.util.Date().getTime()); + statement.setString(4, nickName); + statement.execute(); + } + catch (SQLException e) { + e.printStackTrace(); + } + } + + public static void removePlayerFromDataBase(final UUID uuid) throws SQLException { + final PreparedStatement insert = DatabaseConnection.getConnection().prepareStatement("DELETE FROM nicknames WHERE uuid = ?"); + insert.setString(1, uuid.toString()); + insert.executeUpdate(); + insert.close(); + } + + public static ArrayList getNicknamesList() { + ArrayList nickList = new ArrayList<>(); + String queryNicknames = "SELECT uuid, nickname, date_changed FROM nicknames "; + String queryRequests = "SELECT `requested_nicknames`.`nickname` AS new_nick, `requested_nicknames`.`date_requested`, " + + "`nicknames`.`nickname` AS old_nick, `nicknames`.`date_changed`, `requested_nicknames`.`uuid` " + + "FROM `requested_nicknames`" + + "LEFT JOIN `nicknames` ON `requested_nicknames`.`uuid` = `nicknames`.`uuid` "; + + try { + ResultSet resultSetNicknames = getStringResult(queryNicknames); + while (resultSetNicknames.next()){ + nickList.add(new Nick( + UUID.fromString(resultSetNicknames.getString("uuid")), + resultSetNicknames.getString("nickname"), + resultSetNicknames.getLong("date_changed"))); + } + + ResultSet resultSetRequests = getStringResult(queryRequests); + while (resultSetRequests.next()){ + nickList.add(new Nick( + UUID.fromString(resultSetRequests.getString("uuid")), + resultSetRequests.getString("old_nick"), + resultSetRequests.getLong("date_changed"), + resultSetRequests.getString("new_nick"), + resultSetRequests.getLong("date_requested"))); + } + } catch (SQLException e) { + ALogger.warn("Failed to get nicknames list\n" + Arrays.toString(e.getStackTrace()) + .replace(",", "\n")); + } + return nickList; + } + + public static Nick getNick(UUID uniqueId) { + String getNick = "SELECT nickname, date_changed, uuid FROM nicknames WHERE uuid = ?"; + String getRequest = "SELECT nickname, date_requested, uuid FROM requested_nicknames WHERE uuid = ?"; + + try { + ResultSet resultSetNick = getStringResult(getNick, uniqueId.toString()); + ResultSet resultSetRequest = getStringResult(getRequest, uniqueId.toString()); + String uuid = null; + String currentNick = null; + long dateChanged = 0; + String requestedNick = null; + long dateRequested = 0; + + if (resultSetNick.next()) { + uuid = resultSetNick.getString("uuid"); + currentNick = resultSetNick.getString("nickname"); + dateChanged = resultSetNick.getLong("date_changed"); + } + if (resultSetRequest.next()) { + uuid = resultSetRequest.getString("uuid"); + requestedNick = resultSetRequest.getString("nickname"); + dateRequested = resultSetRequest.getLong("date_requested"); + } + if (uuid != null) { + return new Nick(UUID.fromString(uuid), currentNick, dateChanged, requestedNick, dateRequested); + } + } catch (SQLException e){ + ALogger.warn("Failed to get nicknames for " + + uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace()) + .replace(",", "\n")); + + } + return null; + } + + public static void denyNewNickname(UUID uniqueId) { + String query = "DELETE FROM requested_nicknames WHERE uuid = ?"; + try { + PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(query); + statement.setString(1, uniqueId.toString()); + statement.execute(); + } catch (SQLException e) { + ALogger.warn("Failed to delete requested nickname for " + + uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace()) + .replace(",", "\n")); + } + } + + public static void acceptNewNickname(UUID uniqueId, String newNick){ + String delete = "DELETE FROM requested_nicknames WHERE uuid = ?"; + String update = "INSERT INTO nicknames (uuid, nickname, date_changed) VALUES (?, ?, ?) " + + "ON DUPLICATE KEY UPDATE nickname = ?, date_changed = ?"; + long time = new java.util.Date().getTime(); + + try { + PreparedStatement deleteStatement = DatabaseConnection.getConnection().prepareStatement(delete); + deleteStatement.setString(1, uniqueId.toString()); + + deleteStatement.execute(); + + PreparedStatement updateStatement = DatabaseConnection.getConnection().prepareStatement(update); + updateStatement.setString(1, uniqueId.toString()); + updateStatement.setString(2, newNick); + updateStatement.setLong(3, time); + updateStatement.setString(4, newNick); + updateStatement.setLong(5, time); + + updateStatement.execute(); + } catch (SQLException e) { + ALogger.warn("Failed to accept requested nickname for " + + uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace()) + .replace(",", "\n")); + } + } + + public static void newNicknameRequest(UUID uniqueId, String nickName) { + String requestQuery = "INSERT INTO requested_nicknames (uuid, nickname, date_requested) VALUES (?, ?, ?) " + + "ON DUPLICATE KEY UPDATE nickname = ?, date_requested = ?"; + String nickQuery = "INSERT INTO nicknames (uuid, nickname, date_changed) VALUES (?, ?, 0) " + + "ON DUPLICATE KEY UPDATE uuid = uuid"; + long time = new Date().getTime(); + + try { + PreparedStatement requestPreparedStatement = DatabaseConnection.getConnection().prepareStatement(requestQuery); + requestPreparedStatement.setString(1, uniqueId.toString()); + requestPreparedStatement.setString(2, nickName); + requestPreparedStatement.setLong(3, time); + requestPreparedStatement.setString(4, nickName); + requestPreparedStatement.setLong(5, time); + + requestPreparedStatement.execute(); + + PreparedStatement nickPreparedStatement = DatabaseConnection.getConnection().prepareStatement(nickQuery); + nickPreparedStatement.setString(1, uniqueId.toString()); + nickPreparedStatement.setString(2, null); + + nickPreparedStatement.execute(); + + } catch (SQLException e) { + ALogger.warn("Failed to store requested nickname for " + + uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace()) + .replace(",", "\n")); + } + } + + private static ResultSet getStringResult(final String query, final String... parameters) throws SQLException { + final PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(query); + for (int i = 1; i < parameters.length + 1; ++i) { + statement.setString(i, parameters[i - 1]); + } + return statement.executeQuery(); + } } diff --git a/api/src/main/java/com/alttd/chat/events/NickEvent.java b/api/src/main/java/com/alttd/chat/events/NickEvent.java new file mode 100644 index 0000000..fbf5257 --- /dev/null +++ b/api/src/main/java/com/alttd/chat/events/NickEvent.java @@ -0,0 +1,56 @@ +package com.alttd.chat.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class NickEvent extends Event{ + + String senderName; + String targetName; + String nickName; + NickEventType nickEventType; + + public NickEvent(String senderName, String targetName, String nickName, NickEventType nickEventType) { + this.senderName = senderName; + this.targetName = targetName; + this.nickName = nickName; + this.nickEventType = nickEventType; + } + + public String getSenderName() { + return this.senderName; + } + + public String getTargetName() { + return this.targetName; + } + + public String getNickName() { + return this.nickName; + } + + public NickEventType getNickEventType() { + return this.nickEventType; + } + + private static final HandlerList HANDLERS = new HandlerList(); + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public enum NickEventType { + ACCEPTED, + DENIED, + SET, + RESET + } + +} \ No newline at end of file diff --git a/galaxy/build.gradle.kts b/galaxy/build.gradle.kts index 326f684..171b8c9 100644 --- a/galaxy/build.gradle.kts +++ b/galaxy/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { compileOnly("com.alttd:Galaxy-API:1.19.2-R0.1-SNAPSHOT") // Galaxy compileOnly("com.gitlab.ruany:LiteBansAPI:0.3.5") // move to proxy compileOnly("org.apache.commons:commons-lang3:3.12.0") // needs an alternative, already removed from upstream api and will be removed in server + compileOnly("net.luckperms:api:5.3") // Luckperms } tasks { diff --git a/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java b/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java index cc4501a..300b55e 100755 --- a/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java +++ b/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java @@ -8,6 +8,8 @@ import com.alttd.chat.handler.ChatHandler; import com.alttd.chat.listeners.ChatListener; import com.alttd.chat.listeners.PlayerListener; import com.alttd.chat.listeners.PluginMessage; +import com.alttd.chat.nicknames.Nicknames; +import com.alttd.chat.nicknames.NicknamesEvents; import com.alttd.chat.objects.channels.Channel; import com.alttd.chat.objects.channels.CustomChannel; import com.alttd.chat.util.ALogger; @@ -53,6 +55,7 @@ public class ChatPlugin extends JavaPlugin { registerCommand("chatclear", new ChatClear()); // registerCommand("chatparty", new ChatParty()); registerCommand("p", new PartyChat()); + registerCommand("emotes", new Emotes()); for (Channel channel : Channel.getChannels()) { if (!(channel instanceof CustomChannel customChannel)) continue; this.getServer().getCommandMap().register(channel.getChannelName().toLowerCase(), new ChatChannel(customChannel)); @@ -61,6 +64,11 @@ public class ChatPlugin extends JavaPlugin { messageChannel = Config.MESSAGECHANNEL; getServer().getMessenger().registerOutgoingPluginChannel(this, messageChannel); getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, new PluginMessage()); + +// NicknamesEvents nicknamesEvents = new NicknamesEvents(); +// getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, nicknamesEvents); +// getServer().getPluginManager().registerEvents(nicknamesEvents, this); +// registerCommand("nick", new Nicknames()); } @Override diff --git a/galaxy/src/main/java/com/alttd/chat/nicknames/NickUtilities.java b/galaxy/src/main/java/com/alttd/chat/nicknames/NickUtilities.java new file mode 100644 index 0000000..c2d5a63 --- /dev/null +++ b/galaxy/src/main/java/com/alttd/chat/nicknames/NickUtilities.java @@ -0,0 +1,216 @@ +package com.alttd.chat.nicknames; + +import com.alttd.chat.ChatPlugin; +import com.alttd.chat.config.Config; +import com.alttd.chat.database.Queries; +import com.alttd.chat.objects.Nick; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.awt.*; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.UUID; + +public class NickUtilities +{ + public static String stringRegen; + static String[] blockedCodes = ChatPlugin.getInstance().getConfig().getStringList("Nicknames.BlockedColorCodes").toArray(new String[0]);; + static String[] allowedColorCodes = ChatPlugin.getInstance().getConfig().getStringList("Nicknames.AllowedColorCodes").toArray(new String[0]);; + + public static String applyColor(String message) { + ChatColor hexColor1 = null; + ChatColor hexColor2; + StringBuilder stringBuilder = new StringBuilder(); + message = ChatColor.translateAlternateColorCodes('&', message); + boolean startsWithColor = false; + boolean lastColorMatters = false; + + if (message.matches(".*" + NickUtilities.stringRegen + ".*")) { + String[] split = message.split(NickUtilities.stringRegen); + + ArrayList list = new ArrayList<>(); + int nextIndex = 0; + if (message.indexOf("}") <= 11) { + startsWithColor = true; + list.add(message.substring(0, message.indexOf("}") + 1)); + } + for (String s : split) { + nextIndex += s.length(); + int tmp = message.indexOf("}", nextIndex); + if (tmp < message.length() && tmp>=0) { + list.add(message.substring(nextIndex, tmp + 1)); + nextIndex = tmp + 1; + } + } + + int i; + boolean firstLoop = true; + if (startsWithColor) { + i = -1; + } else { + i = 0; + stringBuilder.append(split[i]); + } + + for (String s : list) { + boolean lesser = s.contains("<"); + boolean bigger = s.contains(">"); + + if (bigger && lesser) { + hexColor2 = ChatColor.of(s.substring(1, s.length() - 3)); + } else if (bigger || lesser) { + hexColor2 = ChatColor.of(s.substring(1, s.length() - 2)); + } else { + hexColor2 = ChatColor.of(s.substring(1, s.length() -1)); + } + + if (firstLoop) { + lastColorMatters = bigger; + hexColor1 = hexColor2; + firstLoop = false; + i++; + continue; + } + + if (lesser && lastColorMatters) { + stringBuilder.append(hexGradient(hexColor1.getColor(), hexColor2.getColor(), split[i])); + } else { + stringBuilder.append(hexColor1).append(split[i]); + } + + hexColor1 = hexColor2; + lastColorMatters = bigger; + i++; + } + if (split.length > i){ + stringBuilder.append(hexColor1).append(split[i]); + } + } + return stringBuilder.length()==0 ? message : stringBuilder.toString(); + } + + public static String removeAllColors(String string) { + + for (final String colorCodes : allowedColorCodes) { + string = string.replace(colorCodes, ""); + } + + return string.replaceAll("\\{#[A-Fa-f0-9]{6}(<)?(>)?}", ""); + } + + static { + NickUtilities.stringRegen = "\\{#[A-Fa-f0-9]{6}(<)?(>)?}"; + } + + public static String hexGradient(Color color1, Color color2, String text){ + double r = color1.getRed(); + double g = color1.getGreen(); + double b = color1.getBlue(); + + double rDifference = (color1.getRed() - color2.getRed()) / ((double) text.length() - 1); + double gDifference = (color1.getGreen() - color2.getGreen()) / ((double) text.length() - 1); + double bDifference = (color1.getBlue() - color2.getBlue()) / ((double) text.length() - 1); + + StringBuilder stringBuilder = new StringBuilder(); + char[] chars = text.toCharArray(); + for (int i = 0; i < text.length(); i++) { + if (i > 0) { + r = r - rDifference; + g = g - gDifference; + b = b - bDifference; + } + stringBuilder.append(ChatColor.of(new Color((int) r, (int) g, (int) b))).append(chars[i]); + } + + return stringBuilder.toString(); + } + + public static void updateCache() { + if (!Nicknames.getInstance().nickCacheUpdate.isEmpty()){ + Nicknames.getInstance().nickCacheUpdate.forEach(uuid ->{ + Nick nick = Queries.getNick(uuid); + if (nick == null){ + Nicknames.getInstance().NickCache.remove(uuid); + } else { + Nicknames.getInstance().NickCache.put(uuid, nick); + } + }); + } + } + + public static boolean validNick(Player sender, OfflinePlayer target, String nickName) { + if (noBlockedCodes(nickName)) { + + String cleanNick = NickUtilities.removeAllColors(nickName); + + if (cleanNick.length() >= 3 && cleanNick.length() <= 16) { + + if (cleanNick.matches("[a-zA-Z0-9_]*") && nickName.length()<=192) {//192 is if someone puts {#xxxxxx<>} in front of every letter + + if (!cleanNick.equalsIgnoreCase(target.getName())){ + for (Nick nick : Nicknames.getInstance().NickCache.values()){ + if (!nick.getUuid().equals(target.getUniqueId()) + && ((nick.getCurrentNickNoColor() != null && nick.getCurrentNickNoColor().equalsIgnoreCase(cleanNick)) + || (nick.getNewNickNoColor() != null && nick.getNewNickNoColor().equalsIgnoreCase(cleanNick)))){ + UUID uuid = nick.getUuid(); + UUID uniqueId = target.getUniqueId(); + if (uniqueId.equals(uuid)){ + ChatPlugin.getInstance().getLogger().info(uuid + " " + uniqueId); + } + sender.sendMessage(applyColor(ChatPlugin.getInstance().getConfig().getString("Messages.NickTaken"))); + return false; + } + } + } + + return true; + + } else { + sender.sendMessage(applyColor(ChatPlugin.getInstance().getConfig().getString("Messages.NickInvalidCharacters"))); + } + } else { + sender.sendMessage(applyColor(ChatPlugin.getInstance().getConfig().getString("Messages.NickLengthInvalid"))); + } + } else { + sender.sendMessage(applyColor(ChatPlugin.getInstance().getConfig().getString("Messages.NickBlockedColorCodes"))); + } + return false; + } + + public static boolean noBlockedCodes(final String getNick) { + for (final String blockedCodes : blockedCodes) { + if (getNick.contains(blockedCodes)) { + return false; + } + } + return true; + } + + public static void bungeeMessageHandled(UUID uniqueId, Player player, String channel) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + + out.writeUTF("Forward"); // So BungeeCord knows to forward it + out.writeUTF("ALL"); + out.writeUTF("NickName" + channel); // The channel name to check if this your data + + ByteArrayOutputStream msgbytes = new ByteArrayOutputStream(); + DataOutputStream msgout = new DataOutputStream(msgbytes); + try { + msgout.writeUTF(uniqueId.toString()); + } catch (IOException exception){ + exception.printStackTrace(); + return; + } + byte[] bytes = msgbytes.toByteArray(); + out.writeShort(bytes.length); + out.write(bytes); + + player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray()); + } +} diff --git a/galaxy/src/main/java/com/alttd/chat/nicknames/Nicknames.java b/galaxy/src/main/java/com/alttd/chat/nicknames/Nicknames.java new file mode 100644 index 0000000..364ebfa --- /dev/null +++ b/galaxy/src/main/java/com/alttd/chat/nicknames/Nicknames.java @@ -0,0 +1,398 @@ +package com.alttd.chat.nicknames; + +import com.alttd.chat.ChatAPI; +import com.alttd.chat.ChatPlugin; +import com.alttd.chat.config.Config; +import com.alttd.chat.database.Queries; +import com.alttd.chat.events.NickEvent; +import com.alttd.chat.managers.ChatUserManager; +import com.alttd.chat.objects.ChatUser; +import com.alttd.chat.objects.Nick; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import net.luckperms.api.LuckPerms; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.sql.SQLException; +import java.util.*; + +public class Nicknames implements CommandExecutor, TabCompleter { + + static Nicknames instance; + HashMap NickCache; + ArrayList nickCacheUpdate; + + public Nicknames() { + instance = this; + NickCache = new HashMap<>(); + nickCacheUpdate = new ArrayList<>(); + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender instanceof Player) { + Player player = (Player) sender; + if (args.length == 0) { + sender.sendMessage(format(helpMessage(sender, HelpType.ALL))); + return true; + } + switch (args[0].toLowerCase()){ + case "set": + if (args.length == 2 && hasPermission(sender, "utility.nick.set")){ + handleNick(player, player, args[1]); + } else if (args.length == 3 && hasPermission(sender, "utility.nick.set.others")){ + OfflinePlayer offlinePlayer = sender.getServer().getOfflinePlayer(args[1]); + + if (offlinePlayer.isOnline() || offlinePlayer.hasPlayedBefore()){ + handleNick(player, offlinePlayer, args[2]); + } else { + sender.sendMessage(format(helpMessage(sender, HelpType.SET_OTHERS))); + } + } else if (args.length > 3){ + sender.sendMessage(format(helpMessage(sender, HelpType.SET_SELF, HelpType.SET_OTHERS))); + } + break; + case "review": + if (args.length == 1 && hasPermission(sender, "utility.nick.review")){ + NicknamesGui nicknamesGui = new NicknamesGui(); + ChatPlugin.getInstance().getServer().getPluginManager().registerEvents(nicknamesGui, ChatPlugin.getInstance()); + nicknamesGui.openInventory(player); + } else { + sender.sendMessage(format(helpMessage(sender, HelpType.REVIEW))); + } + break; + case "request": + if (args.length == 2 && hasPermission(sender, "utility.nick.request")){ + new BukkitRunnable() { + @Override + public void run() { + handleNickRequest(player, args[1]); + } + }.runTaskAsynchronously(ChatPlugin.getInstance()); + } else { + sender.sendMessage(format(helpMessage(sender, HelpType.REQUEST))); + } + break; + case "try": + if (args.length == 2 && hasPermission(sender, "utility.nick.try")){ + LuckPerms api = ChatAPI.get().getLuckPerms(); + if (api != null){ + if (NickUtilities.validNick(player, player, args[1])) { + sender.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickTryout") + .replace("%prefix", api.getUserManager().getUser(player.getUniqueId()) + .getCachedData().getMetaData().getPrefix()) + .replace("%nick%", args[1]))); + } + } else { + sender.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickNoLuckPerms"))); + } + } else { + sender.sendMessage(format(helpMessage(sender, HelpType.TRY))); + } + break; + case "help": + sender.sendMessage(format(helpMessage(sender, HelpType.ALL) + + "For more info on nicknames and how to use rgb colors go to: &bhttps://alttd.com/nicknames&f")); + break; + default: + sender.sendMessage(format(helpMessage(sender, HelpType.ALL))); + } + } else { + sender.sendMessage("Console commands are disabled."); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + List completions = new ArrayList<>(); + if (!sender.hasPermission("utility.nick")) return completions; + + if (args.length == 1){ + List choices = new ArrayList<>(); + if (sender.hasPermission("utility.nick.set")) { + choices.add("set"); + } + if (sender.hasPermission("utility.nick.review")) { + choices.add("review"); + } + if (sender.hasPermission("utility.nick.request")) { + choices.add("request"); + } + if (sender.hasPermission("utility.nick.try")) { + choices.add("try"); + } + choices.add("help"); + + for (String s : choices) { + if (s.startsWith(args[0])) { + completions.add(s); + } + } + } else if (args.length == 2) { + if (args[0].equalsIgnoreCase("set")) { + List choices = new ArrayList<>(); + List onlinePlayers = new ArrayList<>(); + Bukkit.getOnlinePlayers().forEach(a -> onlinePlayers.add(a.getName())); + + if (sender.hasPermission("utility.nick.set.others")) { + choices.addAll(onlinePlayers); + } + + for (String s : choices) { + if (s.startsWith(args[1])) { + completions.add(s); + } + } + } + } + return completions; + } + + private void handleNickRequest(Player player, String nickName) { + if (!NickUtilities.validNick(player, player, nickName)){ + return; + } + + NickUtilities.updateCache(); + UUID uniqueId = player.getUniqueId(); + + if (NickCache.containsKey(uniqueId)){ + Nick nick = NickCache.get(uniqueId); + long timeSinceLastChange = new Date().getTime() - nick.getLastChangedDate(); + long waitTime = ChatPlugin.getInstance().getConfig().getLong("Nicknames.WaitTime"); + if (timeSinceLastChange > waitTime){ + if (nick.hasRequest()){ + player.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickRequestReplaced") + .replace("%oldRequestedNick%", nick.getNewNick()) + .replace("%newRequestedNick%", nickName))); + } + nick.setNewNick(nickName); + nick.setRequestedDate(new Date().getTime()); + } else { + player.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickTooSoon") + .replace("%time%", formatTime((timeSinceLastChange-waitTime)*-1)))); + return; + } + } else { + NickCache.put(uniqueId, new Nick(uniqueId, null, 0, nickName, new Date().getTime())); + } + Queries.newNicknameRequest(uniqueId, nickName); + bungeeMessageRequest(player); + player.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickRequested") + .replace("%nick%", nickName))); + } + + private void bungeeMessageRequest(Player player) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + + UUID uniqueId = player.getUniqueId(); + + out.writeUTF("Forward"); // So BungeeCord knows to forward it + out.writeUTF("ALL"); + out.writeUTF("NickNameRequest"); // The channel name to check if this your data + + ByteArrayOutputStream msgbytes = new ByteArrayOutputStream(); + DataOutputStream msgout = new DataOutputStream(msgbytes); + try { + msgout.writeUTF(uniqueId.toString()); + } catch (IOException exception){ + exception.printStackTrace(); + return; + } + byte[] bytes = msgbytes.toByteArray(); + out.writeShort(bytes.length); + out.write(bytes); + + player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray()); + + Nicknames.getInstance().nickCacheUpdate.add(uniqueId); + } + + private String formatTime(long timeInMillis){ + long second = (timeInMillis / 1000) % 60; + long minute = (timeInMillis / (1000 * 60)) % 60; + long hour = (timeInMillis / (1000 * 60 * 60)) % 24; + long days = (timeInMillis / (1000 * 60 * 60 * 24)); + + StringBuilder stringBuilder = new StringBuilder(); + if (days!=0){ + stringBuilder.append(days).append(" days "); + } + if (days!=0 || hour!=0){ + stringBuilder.append(hour).append(" hours "); + } + if (days!=0 || hour!=0 || minute != 0){ + stringBuilder.append(minute).append(" minutes and "); + } + stringBuilder.append(second).append(" seconds"); + return stringBuilder.toString(); + } + + private void handleNick(Player sender, OfflinePlayer target, final String nickName) { + if (nickName.equalsIgnoreCase("off")) { + + try { + if (target.isOnline()){ + resetNick(target.getPlayer()); + } + Queries.removePlayerFromDataBase(target.getUniqueId()); + NickCache.remove(target.getUniqueId()); + nickCacheUpdate.add(target.getUniqueId()); + } catch (SQLException e) { + e.printStackTrace(); + } + + if (!sender.equals(target)){ + sender.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickResetOthers") + .replace("%player%", target.getName()))); + } + + if (target.isOnline()){ + target.getPlayer().sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickReset"))); + } + + NickEvent nickEvent = new NickEvent(sender.getName(), target.getName(), null, NickEvent.NickEventType.RESET); + nickEvent.callEvent(); + + } else if (NickUtilities.validNick(sender, target, nickName)) { + if (target.isOnline()) { + setNick(target.getPlayer(), nickName); + } else { + NickUtilities.bungeeMessageHandled(target.getUniqueId(), sender, "Set"); + } + + Queries.setNicknameInDatabase(target.getUniqueId(), nickName); + NickEvent nickEvent = new NickEvent(sender.getName(), target.getName(), nickName, NickEvent.NickEventType.SET); + nickEvent.callEvent(); + + if (NickCache.containsKey(target.getUniqueId())){ + Nick nick = NickCache.get(target.getUniqueId()); + nick.setCurrentNick(nickName); + nick.setLastChangedDate(new Date().getTime()); + } else { + NickCache.put(target.getUniqueId(), new Nick(target.getUniqueId(), nickName, new Date().getTime())); + } + + if (!sender.equals(target)){ + sender.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickChangedOthers") + .replace("%targetplayer%", target.getName()) + .replace("%nickname%", nickName))); + if (target.isOnline()) { + target.getPlayer().sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickTargetNickChange") + .replace("%nickname%", getNick(target.getPlayer())) + .replace("%sendernick%", getNick(sender)) + .replace("%player%", target.getName()))); + } + } else if (target.isOnline()){ + target.getPlayer().sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickChanged") + .replace("%nickname%", getNick(target.getPlayer())))); + } + } + } + + private String helpMessage(final CommandSender sender, final HelpType... helpTypes) { + StringBuilder message = new StringBuilder(); + for (HelpType helpType : helpTypes){ + if (helpType.equals(HelpType.ALL)){ + return helpMessage(sender, helpType); + } + message.append(helpMessage(sender, helpType)); + } + return message.toString(); + } + + private String helpMessage(CommandSender sender, HelpType type) { + StringBuilder message = new StringBuilder(); + switch (type){ + case ALL: + message.append(helpMessage(sender, HelpType.SET_SELF)); + message.append(helpMessage(sender, HelpType.SET_OTHERS)); + message.append(helpMessage(sender, HelpType.REQUEST)); + message.append(helpMessage(sender, HelpType.REVIEW)); + message.append(helpMessage(sender, HelpType.TRY)); + break; + case SET_SELF: + if (sender.hasPermission("utility.nick.set")){ + message.append("&6/nick set &f - Sets your nickname to the specified name.\n"); + } + break; + case SET_OTHERS: + if (sender.hasPermission("utility.nick.set.others")){ + message.append("&6/nick set &f - Sets the specified user's nickname to the specified name.\n"); + } + break; + case REQUEST: + if (sender.hasPermission("utility.nick.request")){ + message.append("&6/nick request &f - Requests a username to be reviewed by staff.\n" + + " &7Try using &8/nick try &7 to see if you like the name, you can only change it once per day!\n"); + } + break; + case REVIEW: + if (sender.hasPermission("utility.nick.review")){ + message.append("&6/nick review&f - Opens the nickname review GUI (left click to accept a nick, right click to deny it)\n"); + } + break; + case TRY: + if (sender.hasPermission("utility.nick.try")){ + message.append("&6/nick try &f - Shows you what your nickname will look like in chat.\n"); + } + } + return message.toString(); + } + + private boolean hasPermission(CommandSender sender, String permission) { + if (!sender.hasPermission(permission)){ + sender.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NoPermission"))); + return false; + } + return true; + } + + public void resetNick(final Player player) { + ChatUser user = ChatUserManager.getChatUser(player.getUniqueId()); + user.setDisplayName(player.getDisplayName()); + } + + public String getNick(final Player player) { + ChatUser user = ChatUserManager.getChatUser(player.getUniqueId()); + return user.getNickNameString(); + } + + public void setNick(final Player player, final String nickName) { + ChatUser user = ChatUserManager.getChatUser(player.getUniqueId()); + user.setDisplayName(nickName); + } + +// @Deprecated +// public void setNick(final CommandSender sender, final Player player, final String nickName) { +// Bukkit.getServer().dispatchCommand(sender, "cmi nick " + nickName + " " + player.getName()); +// } + + public static String format(final String m) { + return NickUtilities.applyColor(m); + } + + public static Nicknames getInstance() { + return Nicknames.instance; + } + + private enum HelpType { + ALL, + SET_SELF, + SET_OTHERS, + REVIEW, + REQUEST, + TRY + } +} diff --git a/galaxy/src/main/java/com/alttd/chat/nicknames/NicknamesEvents.java b/galaxy/src/main/java/com/alttd/chat/nicknames/NicknamesEvents.java new file mode 100644 index 0000000..0f9a375 --- /dev/null +++ b/galaxy/src/main/java/com/alttd/chat/nicknames/NicknamesEvents.java @@ -0,0 +1,189 @@ +package com.alttd.chat.nicknames; + +import com.alttd.chat.ChatPlugin; +import com.alttd.chat.config.Config; +import com.alttd.chat.database.Queries; +import com.alttd.chat.objects.Nick; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.util.UUID; + +public class NicknamesEvents implements Listener, PluginMessageListener { + + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onPlayerJoin(PlayerJoinEvent e) { + + new BukkitRunnable() { + @Override + public void run() { + if (Nicknames.instance.NickCache.isEmpty()) { + Queries.getNicknamesList().forEach(nick -> Nicknames.instance.NickCache.put(nick.getUuid(), nick)); + } + + final Player player = e.getPlayer(); + final Nick nick = Queries.getNick(player.getUniqueId()); + + if (nick == null) { + Nicknames.getInstance().resetNick(player); + return; + } + + String nickName = nick.getCurrentNick(); + String strippedNick = Nicknames.getInstance().getNick(player); +// try { +// strippedNick = MiniMessage.miniMessage().stripTokens(Nicknames.getInstance().getNick(player)); +// } catch (NullPointerException ignored) { +// } +// final String strippedNick = CMIChatColor.stripColor(Nicknames.getInstance().getNick(player)); + + //final String cmiNick = Util.CMIChatColor.deColorize(Nicknames.getInstance().getNick(player)); + + if (nickName == null) { + Nicknames.getInstance().resetNick(player); + } else if (!nickName.equals(strippedNick)) { + Nicknames.getInstance().setNick(player, nickName); + } + + Nicknames.getInstance().NickCache.put(e.getPlayer().getUniqueId(), nick); + + if (player.hasPermission("utility.nick.review")) { + int i = 0; + for (Nick iNick : Nicknames.getInstance().NickCache.values()) { + if (iNick.hasRequest()) { + i++; + } + } + + if (i > 0) { + player.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickRequestsOnLogin") + .replace("%amount%", String.valueOf(i)))); + } + } + } + }.runTaskAsynchronously(ChatPlugin.getInstance()); + } + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] message) { + if (!channel.equals(Config.MESSAGECHANNEL)) { + return; + } + + ByteArrayDataInput in = ByteStreams.newDataInput(message); + String subChannel = in.readUTF(); + if (!subChannel.equals("NickNameRequest") && !subChannel.equals("NickNameAccepted") + && !subChannel.equals("NickNameDenied") && !subChannel.equals("NickNameSet")) { + return; + } + UUID playerUUID; + OfflinePlayer offlinePlayer; + String name; + try { + short len = in.readShort(); + byte[] msgbytes = new byte[len]; + in.readFully(msgbytes); + + DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes)); + playerUUID = UUID.fromString(msgin.readUTF()); + offlinePlayer = ChatPlugin.getInstance().getServer().getOfflinePlayer(playerUUID); + name = offlinePlayer.getName() == null ? playerUUID.toString() : offlinePlayer.getName(); + + } catch (Exception e) { + e.printStackTrace(); + return; + } + + switch (subChannel) { + case "NickNameRequest": + String notification = NickUtilities.applyColor(ChatPlugin.getInstance().getConfig().getString("Messages.NickNewRequest") + .replace("%player%", name)); + TextComponent component = new TextComponent(TextComponent.fromLegacyText(NickUtilities.applyColor(notification))); + component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/nick review")); + component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new ComponentBuilder(NickUtilities.applyColor("&6Click this text to review the request!")).create())); + ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> { + if (p.hasPermission("utility.nick.review")) { + p.sendMessage(component); + } + }); + Nicknames.getInstance().nickCacheUpdate.add(playerUUID); + + if (offlinePlayer.isOnline()) { + Nick nick = Queries.getNick(playerUUID); + if (nick != null && nick.getCurrentNick() != null) { + Nicknames.getInstance().setNick(offlinePlayer.getPlayer(), nick.getCurrentNick()); + } + } + break; + case "NickNameAccepted": + final String messageAccepted = ChatColor.GREEN + name + "'s nickname was accepted!"; + ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> { + if (p.hasPermission("utility.nick.review")) { + p.sendMessage(messageAccepted); + } + }); + //No break on purpose + case "NickNameSet": + Nicknames.getInstance().nickCacheUpdate.add(playerUUID); + if (offlinePlayer.isOnline()) { + Nick nick = Queries.getNick(playerUUID); + Player target = Bukkit.getPlayer(playerUUID); + if (target != null && nick != null && nick.getCurrentNick() != null) { + Nicknames.getInstance().setNick(target, nick.getCurrentNick()); + target.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickChanged") + .replace("%nickname%", nick.getCurrentNick()))); + } + } + break; + case "NickNameDenied": + final String messageDenied = ChatColor.RED + name + "'s nickname was denied!"; + Nick nick = Nicknames.getInstance().NickCache.get(playerUUID); + + ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> { + if (p.hasPermission("utility.nick.review")) { + p.sendMessage(messageDenied); + } + }); + + if (nick.getCurrentNick() == null) { + Nicknames.getInstance().NickCache.remove(playerUUID); + } else { + nick.setNewNick(null); + nick.setRequestedDate(0); + + Nicknames.getInstance().NickCache.put(playerUUID, nick); + } + + if (offlinePlayer.isOnline()) { + Player target = Bukkit.getPlayer(playerUUID); + + if (target == null) break; + target.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickNotChanged") + .replace("%nickname%", nick.getCurrentNick()))); + } + break; + } + } + + public static String format(final String m) { + return NickUtilities.applyColor(m); + } +} diff --git a/galaxy/src/main/java/com/alttd/chat/nicknames/NicknamesGui.java b/galaxy/src/main/java/com/alttd/chat/nicknames/NicknamesGui.java new file mode 100644 index 0000000..eb56a28 --- /dev/null +++ b/galaxy/src/main/java/com/alttd/chat/nicknames/NicknamesGui.java @@ -0,0 +1,284 @@ +package com.alttd.chat.nicknames; + +import com.alttd.chat.ChatPlugin; +import com.alttd.chat.database.Queries; +import com.alttd.chat.events.NickEvent; +import com.alttd.chat.objects.Nick; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import static com.alttd.chat.nicknames.Nicknames.format; + +public class NicknamesGui implements Listener { + + private Inventory inv; + private int currentPage; + + public NicknamesGui() { + // Create a new inventory, with no owner (as this isn't a real inventory) + inv = Bukkit.createInventory(null, 36, "Nicknames GUI"); + + // Put the items into the inventory + currentPage = 1; + setItems(currentPage); + } + + public void setItems(int currentPage) { + new BukkitRunnable() { + @Override + public void run() { + inv.clear(); + NickUtilities.updateCache(); + boolean hasNextPage = false; + int i = (currentPage - 1) * 27; //TODO set to 1 or 2 to test + int limit = i / 27; + + for (Nick nick : Nicknames.getInstance().NickCache.values()) { + if (nick.hasRequest()) { + if (limit >= i / 27) { + inv.setItem(i % 27, createPlayerSkull(nick, ChatPlugin.getInstance().getConfig().getStringList("Nicknames.Lore"))); + i++; + } else { + hasNextPage = true; + break; + } + } + } + + if (currentPage != 1) { + inv.setItem(28, createGuiItem(Material.PAPER, "§bPrevious page", + "§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)), + "§aPrevious page: %previousPage%".replace("%previousPage%", String.valueOf(currentPage - 1)))); + } + + if (hasNextPage) { + inv.setItem(36, createGuiItem(Material.PAPER, "§bNext page", + "§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)), + "§aNext page: §b%nextPage%".replace("%nextPage%", String.valueOf(currentPage + 1)))); + } + } + }.runTaskAsynchronously(ChatPlugin.getInstance()); + } + + private ItemStack createPlayerSkull(Nick nick, List lore) { + ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) playerHead.getItemMeta(); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(nick.getUuid()); + + meta.setOwningPlayer(offlinePlayer); + meta.setDisplayName(offlinePlayer.getName()); + + for (int ii = 0; ii < lore.size(); ii++) { + lore.set(ii, format(lore.get(ii) + .replace("%newNick%", nick.getNewNick()) + .replace("%oldNick%", nick.getCurrentNick() == null ? "None" : nick.getCurrentNick()) + .replace("%lastChanged%", nick.getLastChangedDate() == 0 ? "Not Applicable" : nick.getLastChangedDateFormatted()))); + } + + meta.setLore(lore); + playerHead.setItemMeta(meta); + + return playerHead; + } + + // Nice little method to create a gui item with a custom name, and description + private ItemStack createGuiItem(final Material material, final String name, final String... lore) { + final ItemStack item = new ItemStack(material, 1); + final ItemMeta meta = item.getItemMeta(); + + // Set the name of the item + meta.setDisplayName(name); + + // Set the lore of the item + meta.setLore(Arrays.asList(lore)); + + item.setItemMeta(meta); + + return item; + } + + // You can open the inventory with this + public void openInventory(final HumanEntity ent) {//Possibly with a boolean to show if it should get from cache or update cache + ent.openInventory(inv); + } + + // Check for clicks on items + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onInventoryClick(InventoryClickEvent e) { + if (e.getInventory() != inv) return; + + e.setCancelled(true); + + final ItemStack clickedItem = e.getCurrentItem(); + + if (clickedItem == null || clickedItem.getType() == Material.AIR) return; + + final Player p = (Player) e.getWhoClicked(); + + if (clickedItem.getType().equals(Material.PAPER)) { + if (clickedItem.getItemMeta().getDisplayName().equals("Next Page")) { + setItems(currentPage + 1); + } + } else if (clickedItem.getType().equals(Material.PLAYER_HEAD)) { + SkullMeta meta = (SkullMeta) clickedItem.getItemMeta(); + if (meta.hasEnchants()) { + return; + } + OfflinePlayer owningPlayer = meta.getOwningPlayer(); + + if (owningPlayer == null) { + p.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickUserNotFound"))); + return; + } + + new BukkitRunnable() { + @Override + public void run() { + NickUtilities.updateCache(); + + Nick nick; + UUID uniqueId = owningPlayer.getUniqueId(); + if (Nicknames.getInstance().NickCache.containsKey(uniqueId)) { + nick = Nicknames.getInstance().NickCache.get(uniqueId); + } else { + nick = Queries.getNick(uniqueId); + } + + if (nick == null || !nick.hasRequest()) { + p.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickAlreadyHandled") + .replace("%targetPlayer%", clickedItem.getItemMeta().getDisplayName()))); + return; + } + + if (e.isLeftClick()) { + if (owningPlayer.hasPlayedBefore()) { + Queries.acceptNewNickname(uniqueId, nick.getNewNick()); + + String newNick = nick.getNewNick(); + + new BukkitRunnable() { + @Override + public void run() { + NickEvent nickEvent = new NickEvent(e.getWhoClicked().getName(), clickedItem.getItemMeta().getDisplayName(), newNick, NickEvent.NickEventType.ACCEPTED); + nickEvent.callEvent(); + } + }.runTask(ChatPlugin.getInstance()); + + p.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickAccepted") + .replace("%targetPlayer%", clickedItem.getItemMeta().getDisplayName()) + .replace("%newNick%", nick.getNewNick()) + .replace("%oldNick%", nick.getCurrentNick() == null ? clickedItem.getItemMeta().getDisplayName() : nick.getCurrentNick()))); + + if (owningPlayer.isOnline()) { + Nicknames.getInstance().setNick(owningPlayer.getPlayer(), nick.getNewNick()); + owningPlayer.getPlayer().sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickChanged") + .replace("%nickname%", nick.getNewNick()))); + } + + NickUtilities.bungeeMessageHandled(uniqueId, e.getWhoClicked().getServer().getPlayer(e.getWhoClicked().getName()), "Accepted"); + + nick.setCurrentNick(nick.getNewNick()); + nick.setLastChangedDate(new Date().getTime()); + nick.setNewNick(null); + nick.setRequestedDate(0); + + Nicknames.getInstance().NickCache.put(uniqueId, nick); + + ItemStack itemStack = new ItemStack(Material.SKELETON_SKULL); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(clickedItem.getItemMeta().getDisplayName()); + itemMeta.setLore(clickedItem.getLore()); + itemStack.setItemMeta(itemMeta); + e.getInventory().setItem(e.getSlot(), itemStack); + p.updateInventory(); + } else { + p.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.CantFindPlayer") + .replace("%playerName%", clickedItem.getItemMeta().getDisplayName()))); + } + + } else if (e.isRightClick()) { + if (owningPlayer.hasPlayedBefore()) { + Queries.denyNewNickname(uniqueId); + + String newNick = nick.getNewNick(); + + new BukkitRunnable() { + @Override + public void run() { + NickEvent nickEvent = new NickEvent(e.getWhoClicked().getName(), clickedItem.getItemMeta().getDisplayName(), newNick, NickEvent.NickEventType.DENIED); + nickEvent.callEvent(); + } + }.runTask(ChatPlugin.getInstance()); + + p.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickDenied") + .replace("%targetPlayer%", owningPlayer.getName()) + .replace("%newNick%", nick.getNewNick()) + .replace("%oldNick%", nick.getCurrentNick() == null ? owningPlayer.getName() : nick.getCurrentNick()))); + + if (Nicknames.getInstance().NickCache.containsKey(uniqueId) + && Nicknames.getInstance().NickCache.get(uniqueId).getCurrentNick() != null) { + nick.setNewNick(null); + nick.setRequestedDate(0); + Nicknames.getInstance().NickCache.put(uniqueId, nick); + } else { + Nicknames.getInstance().NickCache.remove(uniqueId); + } + + if (owningPlayer.isOnline()) { + Nicknames.getInstance().setNick(owningPlayer.getPlayer(), nick.getCurrentNick() == null ? owningPlayer.getName() : nick.getCurrentNick()); + owningPlayer.getPlayer().sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.NickNotChanged"))); + } + + NickUtilities.bungeeMessageHandled(uniqueId, e.getWhoClicked().getServer().getPlayer(e.getWhoClicked().getName()), "Denied"); + final String messageDenied = ChatColor.RED + owningPlayer.getName() + "'s nickname was denied!"; + ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> { + if (p.hasPermission("utility.nick.review")) { + p.sendMessage(messageDenied); + } + }); + + + ItemStack itemStack = new ItemStack(Material.SKELETON_SKULL); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(clickedItem.getItemMeta().getDisplayName()); + itemMeta.setLore(clickedItem.getLore()); + itemStack.setItemMeta(itemMeta); + e.getInventory().setItem(e.getSlot(), itemStack); + p.updateInventory(); + } else { + p.sendMessage(format(ChatPlugin.getInstance().getConfig().getString("Messages.CantFindPlayer") + .replace("%playerName%", clickedItem.getItemMeta().getDisplayName()))); + } + } + } + }.runTaskAsynchronously(ChatPlugin.getInstance()); + } + } + + // Cancel dragging in our inventory + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onInventoryClick(InventoryDragEvent e) { + if (e.getInventory() == inv) { + e.setCancelled(true); + } + } +} diff --git a/galaxy/src/main/resources/plugin.yml b/galaxy/src/main/resources/plugin.yml index 60a64dd..f674ef8 100755 --- a/galaxy/src/main/resources/plugin.yml +++ b/galaxy/src/main/resources/plugin.yml @@ -33,4 +33,9 @@ commands: p: permission: command.chat.p chatclear: - permission: chat.command.clear-chat \ No newline at end of file + permission: chat.command.clear-chat + emoteslist: + permission: chat.command.clear-chat + aliases: [emotes] + nick: + permission: chat.command.nick \ No newline at end of file diff --git a/velocity/src/main/java/com/alttd/velocitychat/listeners/PluginMessageListener.java b/velocity/src/main/java/com/alttd/velocitychat/listeners/PluginMessageListener.java index 5265521..076a5f5 100755 --- a/velocity/src/main/java/com/alttd/velocitychat/listeners/PluginMessageListener.java +++ b/velocity/src/main/java/com/alttd/velocitychat/listeners/PluginMessageListener.java @@ -1,11 +1,8 @@ package com.alttd.velocitychat.listeners; -import com.alttd.chat.managers.ChatUserManager; -import com.alttd.chat.objects.ChatUser; -import com.alttd.velocitychat.VelocityChat; -import com.alttd.chat.database.Queries; import com.alttd.chat.objects.channels.CustomChannel; import com.alttd.chat.util.ALogger; +import com.alttd.velocitychat.VelocityChat; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import com.velocitypowered.api.event.Subscribe; @@ -17,13 +14,10 @@ import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.api.proxy.server.RegisteredServer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; import java.util.UUID; public class PluginMessageListener { - //todo add an extra listener for nicknames? private final ChannelIdentifier identifier; public PluginMessageListener(ChannelIdentifier identifier){ @@ -45,21 +39,16 @@ public class PluginMessageListener { String channel = in.readUTF(); VelocityChat.getPlugin().getLogger().info("server " + event.getSource()); switch (channel) { - case "globalchat": - VelocityChat.getPlugin().getServerHandler().sendGlobalChat(in.readUTF(), in.readUTF()); - break; - case "globaladminchat": - VelocityChat.getPlugin().getChatHandler().globalAdminChat(in.readUTF()); - break; - case "privatemessage": - VelocityChat.getPlugin().getChatHandler().privateMessage(in.readUTF(), in.readUTF(), in.readUTF()); - break; - case "chatchannel": { + case "globalchat" -> VelocityChat.getPlugin().getServerHandler().sendGlobalChat(in.readUTF(), in.readUTF()); + case "globaladminchat" -> VelocityChat.getPlugin().getChatHandler().globalAdminChat(in.readUTF()); + case "privatemessage" -> + VelocityChat.getPlugin().getChatHandler().privateMessage(in.readUTF(), in.readUTF(), in.readUTF()); + case "chatchannel" -> { String channelName = in.readUTF(); CustomChannel chatChannel = (CustomChannel) CustomChannel.getChatChannel(channelName); if (chatChannel == null) { - ALogger.warn("Received non existent channel" + channelName +"."); + ALogger.warn("Received non existent channel" + channelName + "."); break; } @@ -68,7 +57,7 @@ public class PluginMessageListener { registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData()))); break; } - case "party": { + case "party" -> { VelocityChat.getPlugin().getChatHandler().sendPartyMessage( UUID.fromString(in.readUTF()), in.readUTF(), @@ -76,30 +65,21 @@ public class PluginMessageListener { serverConnection); break; } - case "NickNameAccepted": { - try { - short len = in.readShort(); - byte[] msgbytes = new byte[len]; - in.readFully(msgbytes); - DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes)); - UUID uuid = UUID.fromString(msgin.readUTF()); - ChatUser chatUser = ChatUserManager.getChatUser(uuid); - chatUser.reloadDisplayName(); - - } catch (Exception e) { - e.printStackTrace(); - return; - } - } - default: + // nicknames WIP +// case "NickNameRequest", "NickNameAccepted", "NickNameSet", "NickNameDenied" -> { +// ProxyServer proxy = VelocityChat.getPlugin().getProxy(); +// proxy.getAllServers().forEach(registeredServer -> +// registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData())); +// break; +// } + default -> { VelocityChat.getPlugin().getLogger().info("server " + event.getSource()); ProxyServer proxy = VelocityChat.getPlugin().getProxy(); - for (RegisteredServer registeredServer : proxy.getAllServers()) { registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData()); } - break; + } } }