From 3d850d369877f734e5897ace679b84b035210b44 Mon Sep 17 00:00:00 2001 From: Taah Date: Sun, 24 Apr 2022 16:34:42 -0700 Subject: [PATCH] display a properly parsed nickname with the hover events removed --- api/src/main/java/dev/plex/util/Logger.java | 3 +- server/build.gradle.kts | 1 + server/src/main/java/dev/plex/Sunburst.java | 13 ++- .../dev/plex/command/SunburstCommand.java | 6 ++ .../dev/plex/command/impl/NicknameCMD.java | 29 +++++-- .../main/java/dev/plex/util/AshconInfo.java | 51 ++++++++++++ .../java/dev/plex/util/ComponentUtil.java | 25 ++++++ .../main/java/dev/plex/util/MojangUtils.java | 82 +++++++++++++++++++ server/src/main/resources/messages.yml | 1 + 9 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 server/src/main/java/dev/plex/util/AshconInfo.java create mode 100644 server/src/main/java/dev/plex/util/MojangUtils.java diff --git a/api/src/main/java/dev/plex/util/Logger.java b/api/src/main/java/dev/plex/util/Logger.java index 2a13386..552263d 100644 --- a/api/src/main/java/dev/plex/util/Logger.java +++ b/api/src/main/java/dev/plex/util/Logger.java @@ -1,5 +1,6 @@ package dev.plex.util; +import dev.plex.plugin.SunburstPlugin; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; @@ -8,7 +9,7 @@ public class Logger public static void log(String message) { - Bukkit.getConsoleSender().sendMessage(MiniMessage.miniMessage().deserialize("[Sunburst] " + message)); + Bukkit.getScheduler().runTask(SunburstPlugin.getPlugin(), () -> Bukkit.getConsoleSender().sendMessage(MiniMessage.miniMessage().deserialize("[Sunburst] " + message))); } public static void error(String message) diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 32e2393..e4f1a37 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { annotationProcessor("org.projectlombok:lombok:1.18.22") library("org.json:json:20220320") + library("org.apache.httpcomponents:httpclient:4.5.13") } bukkit { diff --git a/server/src/main/java/dev/plex/Sunburst.java b/server/src/main/java/dev/plex/Sunburst.java index cdcdeda..6365ad3 100644 --- a/server/src/main/java/dev/plex/Sunburst.java +++ b/server/src/main/java/dev/plex/Sunburst.java @@ -12,8 +12,10 @@ import dev.plex.plugin.SunburstPlugin; import dev.plex.storage.FileStorage; import dev.plex.util.ComponentUtil; import dev.plex.util.Configuration; +import dev.plex.util.Logger; import lombok.Getter; import lombok.Setter; +import lombok.extern.java.Log; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.Bukkit; @@ -41,7 +43,16 @@ public final class Sunburst extends SunburstPlugin this.messages.load(); this.getObjectHolder().setPermissionHandler(new PermissionHandlerImpl()); - this.getObjectHolder().setChatRenderer((source, sourceDisplayName, message, viewer) -> ComponentUtil.configComponent("chatFormat", MiniMessage.miniMessage().serialize(source.displayName()), PlainTextComponentSerializer.plainText().serialize(message))); + this.getObjectHolder().setChatRenderer((source, sourceDisplayName, message, viewer) -> { + Logger.log("Spokenz"); + Logger.log(ComponentUtil.mmCustom(sourceDisplayName, ComponentUtil.REGULAR_TAGS)); + return ComponentUtil.configComponent("chatFormat", + ComponentUtil.REGULAR_TAGS, + ComponentUtil.mmCustom(sourceDisplayName, ComponentUtil.REGULAR_TAGS), + PlainTextComponentSerializer.plainText().serialize(message)); + }); + + Logger.debug("Loading"); } @Override diff --git a/server/src/main/java/dev/plex/command/SunburstCommand.java b/server/src/main/java/dev/plex/command/SunburstCommand.java index 06bd776..8718306 100644 --- a/server/src/main/java/dev/plex/command/SunburstCommand.java +++ b/server/src/main/java/dev/plex/command/SunburstCommand.java @@ -9,6 +9,7 @@ import dev.plex.util.CommandUtil; import dev.plex.util.ComponentUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -114,6 +115,11 @@ public abstract class SunburstCommand extends Command implements PluginIdentifia return ComponentUtil.configComponent(entry, objects); } + protected Component confMsg(String entry, TagResolver[] tagResolvers, Object... objects) + { + return ComponentUtil.configComponent(entry, tagResolvers, objects); + } + protected Component usage() { return confMsg("incorrectUsage", getUsage()); diff --git a/server/src/main/java/dev/plex/command/impl/NicknameCMD.java b/server/src/main/java/dev/plex/command/impl/NicknameCMD.java index 77ea000..3ef990f 100644 --- a/server/src/main/java/dev/plex/command/impl/NicknameCMD.java +++ b/server/src/main/java/dev/plex/command/impl/NicknameCMD.java @@ -5,8 +5,12 @@ import dev.plex.command.util.CommandInfo; import dev.plex.command.util.CommandPerms; import dev.plex.player.ISunburstPlayer; import dev.plex.util.ComponentUtil; +import dev.plex.util.Logger; +import dev.plex.util.MojangUtils; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; @@ -32,7 +36,7 @@ public class NicknameCMD extends SunburstCommand { return confMsg("nicknameNotFound"); } - return confMsg("nickname", miniString(sunburstPlayer.displayName())); + return confMsg("nickname", ComponentUtil.REGULAR_TAGS, ComponentUtil.mmCustom(sunburstPlayer.displayName(), ComponentUtil.REGULAR_TAGS)); } if (Bukkit.getOnlinePlayers().stream().anyMatch(p -> p.getName().equalsIgnoreCase(args[0]))) { @@ -48,12 +52,20 @@ public class NicknameCMD extends SunburstCommand target.sendMessage(confMsg("nicknameRemoved")); return confMsg("nicknameRemovedOther", target.getName()); } - String nickname = args[1]; + String nickname = StringUtils.join(args, " ", 1, args.length); nickname = nickname.replace("", "").replace("
", ""); Component newNickname = MiniMessage.miniMessage().deserialize(nickname, ComponentUtil.REGULAR_TAGS); + String rawNick = PlainTextComponentSerializer.plainText().serialize(newNickname); + if (!rawNick.equalsIgnoreCase(target.getName()) && Bukkit.getOfflinePlayer(rawNick).hasPlayedBefore()) + { + if (Bukkit.getOfflinePlayer(nickname).hasPlayedBefore()) + { + return confMsg("nicknameMatchesPlayer"); + } + } sunburstPlayer.displayName(newNickname); - target.sendMessage(confMsg("nicknameSet", nickname)); - return confMsg("nicknameSetOther", target.getName(), nickname); + target.sendMessage(confMsg("nicknameSet", ComponentUtil.REGULAR_TAGS, ComponentUtil.mmCustom(newNickname, ComponentUtil.REGULAR_TAGS))); + return confMsg("nicknameSetOther", ComponentUtil.REGULAR_TAGS, target.getName(), ComponentUtil.mmCustom(newNickname, ComponentUtil.REGULAR_TAGS)); } if (args[0].equalsIgnoreCase("off")) @@ -71,10 +83,15 @@ public class NicknameCMD extends SunburstCommand return confMsg("commandCheckConsole", this.getUsage()); } ISunburstPlayer sunburstPlayer = plugin.getObjectHolder().getStorageSystem().getPlayer(player.getUniqueId()); - String nickname = args[0]; + String nickname = StringUtils.join(args, " "); nickname = nickname.replace("", "").replace("
", ""); Component newNickname = MiniMessage.miniMessage().deserialize(nickname, ComponentUtil.REGULAR_TAGS); + String rawNick = PlainTextComponentSerializer.plainText().serialize(newNickname); + if (!rawNick.equalsIgnoreCase(player.getName()) && MojangUtils.getInfo(rawNick) != null) + { + return confMsg("nicknameMatchesPlayer"); + } sunburstPlayer.displayName(newNickname); - return confMsg("nicknameSet", nickname); + return confMsg("nicknameSet", ComponentUtil.REGULAR_TAGS, ComponentUtil.mmCustom(newNickname, ComponentUtil.REGULAR_TAGS)); } } diff --git a/server/src/main/java/dev/plex/util/AshconInfo.java b/server/src/main/java/dev/plex/util/AshconInfo.java new file mode 100644 index 0000000..d88c6ed --- /dev/null +++ b/server/src/main/java/dev/plex/util/AshconInfo.java @@ -0,0 +1,51 @@ +package dev.plex.util; + +import com.google.gson.annotations.SerializedName; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +public class AshconInfo +{ + private String uuid; + private String username; + + @SerializedName("username_history") + private UsernameHistory[] usernameHistories; + + private Textures textures; + + @Getter + @Setter + @NoArgsConstructor + public static class UsernameHistory + { + private String username; + @SerializedName("changed_at") + private ZonedDateTime zonedDateTime; + } + + @Getter + @Setter + @NoArgsConstructor + public static class Textures + { + private boolean custom; + private boolean slim; + private SkinData raw; + } + + @Getter + @Setter + @NoArgsConstructor + public static class SkinData + { + private String value; + private String signature; + } +} \ No newline at end of file diff --git a/server/src/main/java/dev/plex/util/ComponentUtil.java b/server/src/main/java/dev/plex/util/ComponentUtil.java index 5e019ef..d4c98f1 100644 --- a/server/src/main/java/dev/plex/util/ComponentUtil.java +++ b/server/src/main/java/dev/plex/util/ComponentUtil.java @@ -31,6 +31,31 @@ public class ComponentUtil return value; } + public static String miniString(Component component) + { + return mmCustom(component, TagResolver.standard()); + } + + public static String mmCustom(Component component, TagResolver... tags) + { + return MiniMessage.builder().tags(TagResolver.resolver(tags)).build().serialize(component); + } + + public static Component mini(String message) + { + return mmCustom(message, TagResolver.standard()); + } + + public static Component mmCustom(String message, TagResolver... tags) + { + return MiniMessage.builder().tags(TagResolver.resolver(tags)).build().deserialize(message); + } + + public static Component configComponent(String entry, TagResolver[] tagResolvers, Object... objects) + { + return MiniMessage.builder().tags(TagResolver.resolver(tagResolvers)).build().deserialize(configMessage(entry, objects)); + } + public static Component configComponent(String entry, Object... objects) { return MiniMessage.miniMessage().deserialize(configMessage(entry, objects)); diff --git a/server/src/main/java/dev/plex/util/MojangUtils.java b/server/src/main/java/dev/plex/util/MojangUtils.java new file mode 100644 index 0000000..df02280 --- /dev/null +++ b/server/src/main/java/dev/plex/util/MojangUtils.java @@ -0,0 +1,82 @@ +package dev.plex.util; + +import com.google.common.collect.Maps; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializer; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Map; + +import dev.plex.Sunburst; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.bukkit.scheduler.BukkitRunnable; +import org.json.JSONObject; + +public class MojangUtils +{ + private static final Map CACHED_INFO = Maps.newHashMap(); + public static AshconInfo getInfo(String nameOrUuid) + { + if (CACHED_INFO.containsKey(nameOrUuid)) + { + return CACHED_INFO.get(nameOrUuid); + } + CloseableHttpClient client = HttpClients.createDefault(); + HttpGet get = new HttpGet("https://api.ashcon.app/mojang/v2/user/" + nameOrUuid); + try + { + HttpResponse response = client.execute(get); + if (response == null || response.getEntity() == null) + { + return null; + } + String json = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + JSONObject object = new JSONObject(json); + if (!object.isNull("code") && object.getInt("code") == 404) + { + return null; + } + client.close(); + AshconInfo ashconInfo = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, (JsonDeserializer)(json1, typeOfT, context) -> + ZonedDateTime.ofInstant(Instant.from(DateTimeFormatter.ISO_INSTANT.parse(json1.getAsJsonPrimitive().getAsString())), ZoneId.systemDefault())).create().fromJson(json, AshconInfo.class); + + CACHED_INFO.put(ashconInfo.getUuid(), ashconInfo); + CACHED_INFO.put(ashconInfo.getUsername(), ashconInfo); + + new BukkitRunnable() + { + @Override + public void run() + { + CACHED_INFO.remove(ashconInfo.getUsername()); + CACHED_INFO.remove(ashconInfo.getUuid()); + } + }.runTaskLater(Sunburst.inst(), 20 * 60 * 2); + + Arrays.sort(ashconInfo.getUsernameHistories(), (o1, o2) -> + { + if (o1.getZonedDateTime() == null || o2.getZonedDateTime() == null) + { + return 1; + } + return o1.getZonedDateTime().compareTo(o2.getZonedDateTime()); + }); + + return ashconInfo; + } + catch (IOException e) + { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/server/src/main/resources/messages.yml b/server/src/main/resources/messages.yml index cae693f..459829e 100644 --- a/server/src/main/resources/messages.yml +++ b/server/src/main/resources/messages.yml @@ -28,6 +28,7 @@ nicknameSet: "Your nickname has been set to {0}" # 0 - The targeted player # 1 - The nickname nicknameSetOther: "You have set {0}'s nickname to {1}" +nicknameMatchesPlayer: "This nickname is the same as another player's username" # 0 - Player username # 1 - Message